Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 45 additions & 17 deletions src/main/ts/g0101_0200/s0127_word_ladder/solution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ function ladderLength(beginWord: string, endWord: string, wordList: string[]): n
const wordSet = new Set(wordList)
if (!wordSet.has(endWord)) return 0

const queue = [beginWord]
const queue: string[] = [beginWord]
let steps = 1

while (queue.length > 0) {
Expand All @@ -15,22 +15,8 @@ function ladderLength(beginWord: string, endWord: string, wordList: string[]): n
for (let i = 0; i < levelSize; i++) {
const word = queue.shift()!

// Try changing each letter
for (let pos = 0; pos < word.length; pos++) {
for (let charCode = 97; charCode <= 122; charCode++) {
// 'a' to 'z'
const newChar = String.fromCodePoint(charCode)
if (newChar === word[pos]) continue

const newWord = word.slice(0, pos) + newChar + word.slice(pos + 1)

if (newWord === endWord) return steps + 1

if (wordSet.has(newWord)) {
queue.push(newWord)
wordSet.delete(newWord)
}
}
if (processNextWords(word, endWord, wordSet, queue)) {
return steps + 1
}
}

Expand All @@ -40,4 +26,46 @@ function ladderLength(beginWord: string, endWord: string, wordList: string[]): n
return 0
}

function processNextWords(
word: string,
endWord: string,
wordSet: Set<string>,
queue: string[]
): boolean {
for (let pos = 0; pos < word.length; pos++) {
if (tryAllReplacements(word, pos, endWord, wordSet, queue)) {
return true
}
}
return false
}


function tryAllReplacements(
word: string,
pos: number,
endWord: string,
wordSet: Set<string>,
queue: string[],
): boolean {
for (let c = 97; c <= 122; c++) {
const char = String.fromCodePoint(c)
if (char === word[pos]) continue

const newWord = replaceChar(word, pos, char)

if (newWord === endWord) return true

if (wordSet.has(newWord)) {
queue.push(newWord)
wordSet.delete(newWord)
}
}
return false
}

function replaceChar(word: string, index: number, char: string): string {
return word.slice(0, index) + char + word.slice(index + 1)
}

export { ladderLength }
4 changes: 2 additions & 2 deletions src/main/ts/g0301_0400/s0383_ransom_note/solution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ function canConstruct(ransomNote: string, magazine: string): boolean {
const freq: number[] = new Array(26).fill(0)
let remaining = ransomNote.length
for (let i = 0; i < remaining; i++) {
freq[ransomNote.charCodeAt(i) - 97]++
freq[ransomNote.codePointAt(i)! - 97]++
}
for (let i = 0; i < magazine.length && remaining > 0; i++) {
const index = magazine.charCodeAt(i) - 97
const index = magazine.codePointAt(i)! - 97
if (freq[index] > 0) {
freq[index]--
remaining--
Expand Down
16 changes: 8 additions & 8 deletions src/main/ts/g0301_0400/s0399_evaluate_division/solution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ function calcEquation(equations: [string, string][], values: number[], queries:
for (const [x, y] of equations) {
if (!root.has(x)) {
root.set(x, x)
rate.set(x, 1.0)
rate.set(x, 1)
}
if (!root.has(y)) {
root.set(y, y)
rate.set(y, 1.0)
rate.set(y, 1)
}
}
for (let i = 0; i < equations.length; ++i) {
Expand All @@ -25,23 +25,23 @@ function calcEquation(equations: [string, string][], values: number[], queries:
const result: number[] = []
for (const [x, y] of queries) {
if (!root.has(x) || !root.has(y)) {
result.push(-1.0)
result.push(-1)
} else {
const rootX = findRoot(x, x, 1.0, root, rate)
const rootY = findRoot(y, y, 1.0, root, rate)
const rootX = findRoot(x, x, 1, root, rate)
const rootY = findRoot(y, y, 1, root, rate)
if (rootX === rootY) {
result.push(rate.get(x)! / rate.get(y)!)
} else {
result.push(-1.0)
result.push(-1)
}
}
}
return result
}

function union(x: string, y: string, value: number, root: MapType, rate: RateType): void {
const rootX = findRoot(x, x, 1.0, root, rate)
const rootY = findRoot(y, y, 1.0, root, rate)
const rootX = findRoot(x, x, 1, root, rate)
const rootY = findRoot(y, y, 1, root, rate)

if (rootX !== rootY) {
root.set(rootX, rootY)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@

function expand(a: string[], l: number, r: number, res: number[]): void {
while (l >= 0 && r < a.length) {
if (a[l] !== a[r]) {
return
} else {
if (a[l] === a[r]) {
res[0]++
l--
r++
} else {
return
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/ts/g0701_0800/s0763_partition_labels/solution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ function partitionLabels(s: string): number[] {
const map = new Map<string, [number, number]>()
for (let i = 0; i < s.length; i++) {
const c = s[i]
if (!map.has(c)) map.set(c, [i, i])
else map.get(c)[1] = i
if (map.has(c)) map.get(c)[1] = i
else map.set(c, [i, i])
}
const arr = Array.from(map.values())
arr.sort((v1, v2) => v1[0] - v2[0])
Expand Down
41 changes: 31 additions & 10 deletions src/main/ts/g0901_1000/s0909_snakes_and_ladders/solution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,53 @@
function snakesAndLadders(board: number[][]): number {
const size = board.length
const target = size * size
const visited: boolean[] = new Array(target).fill(false)
const queue: number[] = []
queue.push(1)

const visited = new Array<boolean>(target).fill(false)
const queue: number[] = [1]

visited[0] = true
let steps = 0

while (queue.length > 0) {
const levelSize = queue.length

for (let i = 0; i < levelSize; i++) {
const current = queue.shift()!

if (current === target) {
return steps
}
for (let next = current + 1; next <= Math.min(current + 6, target); next++) {
if (visited[next - 1]) continue
visited[next - 1] = true
const [row, col] = indexToPosition(next, size)
const destination = board[row][col] === -1 ? next : board[row][col]
queue.push(destination)
}

enqueueNextMoves(current, target, size, board, visited, queue)
}

steps++
}

return -1
}

function enqueueNextMoves(
current: number,
target: number,
size: number,
board: number[][],
visited: boolean[],
queue: number[],
): void {
for (let next = current + 1; next <= Math.min(current + 6, target); next++) {
if (visited[next - 1]) continue

visited[next - 1] = true
queue.push(resolveDestination(next, size, board))
}
}

function resolveDestination(index: number, size: number, board: number[][]): number {
const [row, col] = indexToPosition(index, size)
return board[row][col] === -1 ? index : board[row][col]
}

function indexToPosition(index: number, size: number): [number, number] {
const row = size - 1 - Math.floor((index - 1) / size)
let col: number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { findMedianSortedArrays } from 'src/main/ts/g0001_0100/s0004_median_of_t
import { expect, test } from 'vitest'

test('findMedianSortedArrays', () => {
expect(findMedianSortedArrays([1, 3], [2])).toEqual(2.0)
expect(findMedianSortedArrays([1, 3], [2])).toEqual(2)
})

test('findMedianSortedArrays2', () => {
Expand Down
4 changes: 2 additions & 2 deletions src/test/ts/g0001_0100/s0015_3sum/solution.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ test('threeSum', () => {
})

test('threeSum2', () => {
expect(threeSum([])).toEqual(Array())
expect(threeSum([])).toEqual(new Array())
})

test('threeSum3', () => {
expect(threeSum([0])).toEqual(Array())
expect(threeSum([0])).toEqual(new Array())
})
4 changes: 2 additions & 2 deletions src/test/ts/g0001_0100/s0050_powx_n/solution.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { myPow } from 'src/main/ts/g0001_0100/s0050_powx_n/solution'
import { expect, test } from 'vitest'

test('myPow', () => {
expect(myPow(2.0, 10)).toEqual(1024.0)
expect(myPow(2, 10)).toEqual(1024)
})

test('myPow2', () => {
expect(myPow(2.1, 3)).toEqual(9.261000000000001)
})

test('myPow3', () => {
expect(myPow(2.0, -2)).toEqual(0.25)
expect(myPow(2, -2)).toEqual(0.25)
})
4 changes: 2 additions & 2 deletions src/test/ts/g0101_0200/s0155_min_stack/solution.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { expect, test } from 'vitest'
test('minStack', () => {
const minStack = new MinStack()
minStack.push(-2)
minStack.push(0)
minStack.push(-3)
minStack.push(0) //NOSONAR
minStack.push(-3) //NOSONAR
expect(minStack.getMin()).toEqual(-3)
minStack.pop()
expect(minStack.top()).toEqual(0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ test('medianFinder', () => {
medianFinder.addNum(2)
expect(medianFinder.findMedian()).toEqual(1.5)
medianFinder.addNum(3)
expect(medianFinder.findMedian()).toEqual(2.0)
expect(medianFinder.findMedian()).toEqual(2)
})

test('medianFinder2', () => {
const medianFinder = new MedianFinder()
medianFinder.addNum(1)
medianFinder.addNum(3)
medianFinder.addNum(-1)
expect(medianFinder.findMedian()).toEqual(1.0)
expect(medianFinder.findMedian()).toEqual(1)
})

test('medianFinder3', () => {
Expand All @@ -26,7 +26,7 @@ test('medianFinder3', () => {
medianFinder.addNum(-3)
medianFinder.addNum(-4)
medianFinder.addNum(-5)
expect(medianFinder.findMedian()).toEqual(-3.0)
expect(medianFinder.findMedian()).toEqual(-3)
})

test('medianFinder4', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,24 @@ import { RandomizedSet } from 'src/main/ts/g0301_0400/s0380_insert_delete_getran
import { expect, test } from 'vitest'

test('randomizedSet', () => {
const result: string[] = []
let randomizedSet: RandomizedSet | null = null
result.push(randomizedSet + '')
randomizedSet = new RandomizedSet()
result.push(randomizedSet.insert(1) + '')
result.push(randomizedSet.remove(2) + '')
result.push(randomizedSet.insert(2) + '')
const random = randomizedSet.getRandom()
result.push(random + '')
result.push(randomizedSet.remove(1) + '')
result.push(randomizedSet.insert(2) + '')
result.push(randomizedSet.getRandom() + '')
const expected = ['null', 'true', 'false', 'true', '1', 'true', 'false', '2']
let randomizedSet: RandomizedSet = new RandomizedSet()

const result = [
null,
randomizedSet.insert(1),
randomizedSet.remove(2),
randomizedSet.insert(2),
randomizedSet.getRandom(),
randomizedSet.remove(1),
randomizedSet.insert(2),
randomizedSet.getRandom(),
].map(String)

const random = Number(result[4])

const expected1 = ['null', 'true', 'false', 'true', '1', 'true', 'false', '2']
const expected2 = ['null', 'true', 'false', 'true', '2', 'true', 'false', '2']
if (random === 1) {
expect(result).toEqual(expected)
} else {
expect(result).toEqual(expected2)
}

expect(result).toEqual(random === 1 ? expected1 : expected2)
})

10 changes: 5 additions & 5 deletions src/test/ts/g0301_0400/s0399_evaluate_division/solution.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ test('calcEquation', () => {
['a', 'b'],
['b', 'c'],
] as [string, string][]
const values = [2.0, 3.0]
const values = [2, 3]
const queries = [
['a', 'c'],
['b', 'a'],
['a', 'e'],
['a', 'a'],
['x', 'x'],
] as [string, string][]
const expected = [6.0, 0.5, -1.0, 1.0, -1.0]
const expected = [6, 0.5, -1, 1, -1]
expect(calcEquation(equations, values, queries)).toEqual(expected)
})

Expand All @@ -25,14 +25,14 @@ test('calcEquation2', () => {
['b', 'c'],
['bc', 'cd'],
] as [string, string][]
const values = [1.5, 2.5, 5.0]
const values = [1.5, 2.5, 5]
const queries = [
['a', 'c'],
['c', 'b'],
['bc', 'cd'],
['cd', 'bc'],
] as [string, string][]
const expected = [3.75, 0.4, 5.0, 0.2]
const expected = [3.75, 0.4, 5, 0.2]
expect(calcEquation(equations, values, queries)).toEqual(expected)
})

Expand All @@ -45,6 +45,6 @@ test('calcEquation3', () => {
['a', 'c'],
['x', 'y'],
] as [string, string][]
const expected = [0.5, 2.0, -1.0, -1.0]
const expected = [0.5, 2, -1, -1]
expect(calcEquation(equations, values, queries)).toEqual(expected)
})
Loading