LeetCode 75
https://leetcode.cn/study-plan/leetcode_75/
day01
一维数组的动态和
https://leetcode.cn/problems/running-sum-of-1d-array/
function runningSum(nums: number[]): number[] {
const len = nums.length
for (let i = 1; i < len; i++) {
nums[i] += nums[i - 1]
}
return nums
}
function runningSum(nums: number[]): number[] {
const len = nums.length
for (let i = 1; i < len; i++) {
nums[i] += nums[i - 1]
}
return nums
}
寻找数组的中心下标
https://leetcode.cn/problems/find-pivot-index/
function pivotIndex(nums: number[]): number {
const total = nums.reduce((pre, cur) => pre + cur, 0)
const len = nums.length
let sum = 0
for (let i = 0; i < len; i++) {
if (2 * sum + nums[i] === total) {
return i
}
sum += nums[i]
}
return -1
}
function pivotIndex(nums: number[]): number {
const total = nums.reduce((pre, cur) => pre + cur, 0)
const len = nums.length
let sum = 0
for (let i = 0; i < len; i++) {
if (2 * sum + nums[i] === total) {
return i
}
sum += nums[i]
}
return -1
}
day02
同构字符串
https://leetcode.cn/problems/isomorphic-strings/
function isIsomorphic(s: string, t: string): boolean {
const sMap = new Map<string, string>()
const tMap = new Map<string, string>()
const len = s.length
for (let i = 0; i < len; i++) {
const x = s[i]
const y = t[i]
if (
sMap.has(x) && sMap.get(x) !== y ||
tMap.has(y) && tMap.get(y) !== x
) {
return false
}
sMap.set(x, y)
tMap.set(y, x)
}
return true
}
function isIsomorphic(s: string, t: string): boolean {
const sMap = new Map<string, string>()
const tMap = new Map<string, string>()
const len = s.length
for (let i = 0; i < len; i++) {
const x = s[i]
const y = t[i]
if (
sMap.has(x) && sMap.get(x) !== y ||
tMap.has(y) && tMap.get(y) !== x
) {
return false
}
sMap.set(x, y)
tMap.set(y, x)
}
return true
}
判断子序列
https://leetcode.cn/problems/is-subsequence/
function isSubsequence(s: string, t: string): boolean {
const sLen = s.length
const tLen = t.length
let i = 0;
let j = 0;
while (i < sLen && j < tLen) {
if (s[i] === t[j]) {
i++
}
j++
}
return i == sLen
}
function isSubsequence(s: string, t: string): boolean {
const sLen = s.length
const tLen = t.length
let i = 0;
let j = 0;
while (i < sLen && j < tLen) {
if (s[i] === t[j]) {
i++
}
j++
}
return i == sLen
}
day03
合并两个有序链表
https://leetcode.cn/problems/merge-two-sorted-lists/
function mergeTwoLists(list1: ListNode | null, list2: ListNode | null): ListNode | null {
const dummy = new ListNode()
let curr = dummy
while (list1 && list2) {
if (list1.val <= list2.val) {
curr.next = list1
list1 = list1.next
} else {
curr.next = list2
list2 = list2.next
}
curr = curr.next
}
curr.next = list1 || list2
return dummy.next
}
function mergeTwoLists(list1: ListNode | null, list2: ListNode | null): ListNode | null {
const dummy = new ListNode()
let curr = dummy
while (list1 && list2) {
if (list1.val <= list2.val) {
curr.next = list1
list1 = list1.next
} else {
curr.next = list2
list2 = list2.next
}
curr = curr.next
}
curr.next = list1 || list2
return dummy.next
}
function mergeTwoLists(list1: ListNode | null, list2: ListNode | null): ListNode | null {
if (list1 === null) return list2
if (list2 === null) return list1
if (list1.val <= list2.val) {
list1.next = mergeTwoLists(list1.next, list2)
return list1
}
list2.next = mergeTwoLists(list2.next, list1)
return list2
}
function mergeTwoLists(list1: ListNode | null, list2: ListNode | null): ListNode | null {
if (list1 === null) return list2
if (list2 === null) return list1
if (list1.val <= list2.val) {
list1.next = mergeTwoLists(list1.next, list2)
return list1
}
list2.next = mergeTwoLists(list2.next, list1)
return list2
}
反转链表
https://leetcode.cn/problems/reverse-linked-list/
function reverseList(head: ListNode | null): ListNode | null {
let prev = null
let curr = head
while (curr) {
const next = curr.next
curr.next = prev
prev = curr
curr = next
}
return prev
}
function reverseList(head: ListNode | null): ListNode | null {
let prev = null
let curr = head
while (curr) {
const next = curr.next
curr.next = prev
prev = curr
curr = next
}
return prev
}

function reverseList(head: ListNode | null): ListNode | null {
if (head == null || head.next == null) {
return head
}
const curr = reverseList(head.next)
head.next.next = head
head.next = null
return curr
}
function reverseList(head: ListNode | null): ListNode | null {
if (head == null || head.next == null) {
return head
}
const curr = reverseList(head.next)
head.next.next = head
head.next = null
return curr
}
day04
链表的中间节点
https://leetcode.cn/problems/middle-of-the-linked-list/
function middleNode(head: ListNode | null): ListNode | null {
let n = 0;
let curr = head
while (curr) {
n++
curr = curr.next
}
let k = 0;
curr = head
while(k < Math.trunc(n / 2)) {
k++
curr = curr.next
}
return curr
}
function middleNode(head: ListNode | null): ListNode | null {
let n = 0;
let curr = head
while (curr) {
n++
curr = curr.next
}
let k = 0;
curr = head
while(k < Math.trunc(n / 2)) {
k++
curr = curr.next
}
return curr
}
function middleNode(head: ListNode | null): ListNode | null {
let slow = head
let fast = head
while (fast && fast.next) {
slow = slow.next
fast = fast.next.next
}
return slow
}
function middleNode(head: ListNode | null): ListNode | null {
let slow = head
let fast = head
while (fast && fast.next) {
slow = slow.next
fast = fast.next.next
}
return slow
}
环形链表2
https://leetcode.cn/problems/linked-list-cycle-ii/
function detectCycle(head: ListNode | null): ListNode | null {
const visited = new Set()
while (head) {
if (visited.has(head)) return head
visited.add(head)
head = head.next
}
return null
}
function detectCycle(head: ListNode | null): ListNode | null {
const visited = new Set()
while (head) {
if (visited.has(head)) return head
visited.add(head)
head = head.next
}
return null
}
function detectCycle(head: ListNode | null): ListNode | null {
if (head === null) return null
let slow = head
let fast = head
while (fast.next && fast.next.next) {
slow = slow.next
fast = fast.next.next
if (slow === fast) {
fast = head
while (fast !== slow) {
fast = fast.next
slow = slow.next
}
return fast
}
}
return null
}
function detectCycle(head: ListNode | null): ListNode | null {
if (head === null) return null
let slow = head
let fast = head
while (fast.next && fast.next.next) {
slow = slow.next
fast = fast.next.next
if (slow === fast) {
fast = head
while (fast !== slow) {
fast = fast.next
slow = slow.next
}
return fast
}
}
return null
}

day05
买卖股票的最佳时机
https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/
function maxProfit(prices: number[]): number {
let min = Infinity
let max = 0
for (const price of prices) {
min = Math.min(min, price)
max = Math.max(max, price - min)
}
return max
}
function maxProfit(prices: number[]): number {
let min = Infinity
let max = 0
for (const price of prices) {
min = Math.min(min, price)
max = Math.max(max, price - min)
}
return max
}
最长回文串
https://leetcode.cn/problems/longest-palindrome/
function longestPalindrome(s: string): number {
const visited = new Set()
let max = 0
for (const key of s) {
if (visited.has(key)) {
visited.delete(key)
max += 2
} else {
visited.add(key)
}
}
return visited.size ? max + 1 : max
}
function longestPalindrome(s: string): number {
const visited = new Set()
let max = 0
for (const key of s) {
if (visited.has(key)) {
visited.delete(key)
max += 2
} else {
visited.add(key)
}
}
return visited.size ? max + 1 : max
}
day06
N 叉树的前序遍历
https://leetcode.cn/problems/n-ary-tree-preorder-traversal/
interface Node {
val: number
children: Node[]
}
function preorder(root: Node | null): number[] {
const ans = []
helper(root, ans)
return ans
}
function helper(node: Node | null, ans: number[]) {
if (!node) return
ans.push(node.val)
node.children.forEach(item => {
helper(item, ans)
})
}
interface Node {
val: number
children: Node[]
}
function preorder(root: Node | null): number[] {
const ans = []
helper(root, ans)
return ans
}
function helper(node: Node | null, ans: number[]) {
if (!node) return
ans.push(node.val)
node.children.forEach(item => {
helper(item, ans)
})
}
interface Node {
val: number
children: Node[]
}
function preorder(root: Node | null): number[] {
if(!root) return []
const ans = []
const stack = [root]
while (stack.length) {
const node = stack.pop()
ans.push(node.val)
stack.push(...node.children.reverse())
}
return ans
}
interface Node {
val: number
children: Node[]
}
function preorder(root: Node | null): number[] {
if(!root) return []
const ans = []
const stack = [root]
while (stack.length) {
const node = stack.pop()
ans.push(node.val)
stack.push(...node.children.reverse())
}
return ans
}
二叉树的层序遍历
https://leetcode.cn/problems/binary-tree-level-order-traversal/
function levelOrder(root: TreeNode | null): number[][] {
if (!root) return []
const ans = []
const queue = [
{
layer: 0,
node: root
}
]
while (queue.length) {
const { layer, node } = queue.shift()
if (!ans[layer]) {
ans[layer] = []
}
ans[layer].push(node.val)
node.left && queue.push({
layer: layer + 1,
node: node.left
})
node.right && queue.push({
layer: layer + 1,
node: node.right
})
}
return ans
}
function levelOrder(root: TreeNode | null): number[][] {
if (!root) return []
const ans = []
const queue = [
{
layer: 0,
node: root
}
]
while (queue.length) {
const { layer, node } = queue.shift()
if (!ans[layer]) {
ans[layer] = []
}
ans[layer].push(node.val)
node.left && queue.push({
layer: layer + 1,
node: node.left
})
node.right && queue.push({
layer: layer + 1,
node: node.right
})
}
return ans
}
function levelOrder(root: TreeNode | null): number[][] {
if (!root) return []
const ans = []
const queue = [root]
let len: number
while (len = queue.length) {
ans.push([])
while (len--) {
const n = queue.shift()
ans[ans.length - 1].push(n.val)
n.left && queue.push(n.left)
n.right && queue.push(n.right)
}
}
return ans
}
function levelOrder(root: TreeNode | null): number[][] {
if (!root) return []
const ans = []
const queue = [root]
let len: number
while (len = queue.length) {
ans.push([])
while (len--) {
const n = queue.shift()
ans[ans.length - 1].push(n.val)
n.left && queue.push(n.left)
n.right && queue.push(n.right)
}
}
return ans
}
function levelOrder(root: TreeNode | null): number[][] {
const ans = []
helper(root, 0, ans)
return ans
}
function helper(node: TreeNode | null, l: number, ans: number[][]) {
if (!node) return
if (!ans[l]) ans[l] = []
ans[l].push(node.val)
node.left && helper(node.left, l + 1, ans)
node.right && helper(node.right, l + 1, ans)
}
function levelOrder(root: TreeNode | null): number[][] {
const ans = []
helper(root, 0, ans)
return ans
}
function helper(node: TreeNode | null, l: number, ans: number[][]) {
if (!node) return
if (!ans[l]) ans[l] = []
ans[l].push(node.val)
node.left && helper(node.left, l + 1, ans)
node.right && helper(node.right, l + 1, ans)
}
day07
二分查找
https://leetcode.cn/problems/binary-search/
function search(nums: number[], target: number): number {
let start = 0
let end = nums.length - 1
while (start <= end) {
const mid = start + Math.floor((end - start) / 2)
const num = nums[mid]
if (num < target) {
start = mid + 1
} else if (num > target) {
end = mid - 1
} else {
return mid
}
}
return -1
}
function search(nums: number[], target: number): number {
let start = 0
let end = nums.length - 1
while (start <= end) {
const mid = start + Math.floor((end - start) / 2)
const num = nums[mid]
if (num < target) {
start = mid + 1
} else if (num > target) {
end = mid - 1
} else {
return mid
}
}
return -1
}
第一个错误的版本
https://leetcode.cn/problems/first-bad-version/
var solution = function(isBadVersion: any) {
return function(n: number): number {
let start = 1
let end = n
while (start <= end) {
const mid = start + Math.floor((end - start) / 2)
if (isBadVersion(mid)) {
end = mid - 1
} else {
start = mid + 1
}
}
return start
}
}
var solution = function(isBadVersion: any) {
return function(n: number): number {
let start = 1
let end = n
while (start <= end) {
const mid = start + Math.floor((end - start) / 2)
if (isBadVersion(mid)) {
end = mid - 1
} else {
start = mid + 1
}
}
return start
}
}
day08
验证二叉搜索树
https://leetcode.cn/problems/validate-binary-search-tree/
function isValidBST(root: TreeNode | null): boolean {
return helper(root, -Infinity, +Infinity)
}
function helper(root: TreeNode, lower: number, upper: number) {
if (!root) return true
if (root.val <= lower || root.val >= upper) return false
return helper(root.left, lower, root.val) && helper(root.right, root.val, upper)
}
function isValidBST(root: TreeNode | null): boolean {
return helper(root, -Infinity, +Infinity)
}
function helper(root: TreeNode, lower: number, upper: number) {
if (!root) return true
if (root.val <= lower || root.val >= upper) return false
return helper(root.left, lower, root.val) && helper(root.right, root.val, upper)
}
function isValidBST(root: TreeNode | null): boolean {
const stack = []
let value = -Infinity
while (stack.length || root) {
while (root) {
stack.push(root)
root = root.left
}
root = stack.pop()
if (root.val <= value) return false
value = root.val
root = root.right
}
return true
}
function isValidBST(root: TreeNode | null): boolean {
const stack = []
let value = -Infinity
while (stack.length || root) {
while (root) {
stack.push(root)
root = root.left
}
root = stack.pop()
if (root.val <= value) return false
value = root.val
root = root.right
}
return true
}
二叉搜索树的最近公共祖先
https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/
function lowestCommonAncestor(
root: TreeNode | null,
p: TreeNode | null,
q: TreeNode | null
): TreeNode | null {
if (p.val < root.val && q.val < root.val) {
return lowestCommonAncestor(root.left, p, q)
}
if (p.val > root.val && q.val > root.val) {
return lowestCommonAncestor(root.right, p, q)
}
return root
}
function lowestCommonAncestor(
root: TreeNode | null,
p: TreeNode | null,
q: TreeNode | null
): TreeNode | null {
if (p.val < root.val && q.val < root.val) {
return lowestCommonAncestor(root.left, p, q)
}
if (p.val > root.val && q.val > root.val) {
return lowestCommonAncestor(root.right, p, q)
}
return root
}
function lowestCommonAncestor(
root: TreeNode | null,
p: TreeNode | null,
q: TreeNode | null
): TreeNode | null {
while (root) {
if (p.val < root.val && q.val < root.val) {
root = root.left
} else if (p.val > root.val && q.val > root.val) {
root = root.right
} else {
break
}
}
return root
}
function lowestCommonAncestor(
root: TreeNode | null,
p: TreeNode | null,
q: TreeNode | null
): TreeNode | null {
while (root) {
if (p.val < root.val && q.val < root.val) {
root = root.left
} else if (p.val > root.val && q.val > root.val) {
root = root.right
} else {
break
}
}
return root
}
day09
图像渲染
https://leetcode.cn/problems/flood-fill/
function floodFill(image: number[][], sr: number, sc: number, newColor: number): number[][] {
if (!image.length) return []
const m = image.length
const n = image[0].length
const d = [[0, 1], [1, 0], [0, -1], [-1, 0]]
const currentColor = image[sr][sc]
const queue = [[sr, sc]]
while (queue.length) {
const [i, j] = queue.shift()
if (image[i][j] !== currentColor || image[i][j] === newColor) continue
image[i][j] = newColor
for (const [dx, dy] of d) {
const x = dx + i
const y = dy + j
if (x >= 0 && x < m && y >= 0 && y < n) queue.push([x, y])
}
}
return image
}
function floodFill(image: number[][], sr: number, sc: number, newColor: number): number[][] {
if (!image.length) return []
const m = image.length
const n = image[0].length
const d = [[0, 1], [1, 0], [0, -1], [-1, 0]]
const currentColor = image[sr][sc]
const queue = [[sr, sc]]
while (queue.length) {
const [i, j] = queue.shift()
if (image[i][j] !== currentColor || image[i][j] === newColor) continue
image[i][j] = newColor
for (const [dx, dy] of d) {
const x = dx + i
const y = dy + j
if (x >= 0 && x < m && y >= 0 && y < n) queue.push([x, y])
}
}
return image
}
function floodFill(image: number[][], sr: number, sc: number, newColor: number): number[][] {
if (!image.length) return []
const m = image.length
const n = image[0].length
const d = [[0, 1], [1, 0], [0, -1], [-1, 0]]
const currentColor = image[sr][sc]
const fill = (i: number, j: number) => {
if (image[i][j] !== currentColor || image[i][j] === newColor) return
image[i][j] = newColor
for (const [dx, dy] of d) {
const x = dx + i
const y = dy + j
if (x >= 0 && x < m && y >= 0 && y < n) fill(x, y)
}
}
fill(sr, sc)
return image
}
function floodFill(image: number[][], sr: number, sc: number, newColor: number): number[][] {
if (!image.length) return []
const m = image.length
const n = image[0].length
const d = [[0, 1], [1, 0], [0, -1], [-1, 0]]
const currentColor = image[sr][sc]
const fill = (i: number, j: number) => {
if (image[i][j] !== currentColor || image[i][j] === newColor) return
image[i][j] = newColor
for (const [dx, dy] of d) {
const x = dx + i
const y = dy + j
if (x >= 0 && x < m && y >= 0 && y < n) fill(x, y)
}
}
fill(sr, sc)
return image
}
岛屿数量
https://leetcode.cn/problems/number-of-islands/
function numIslands(grid: string[][]): number {
const m = grid.length
const n = grid[0].length
const d = [[0, 1], [1, 0], [0, -1], [-1, 0]]
let count = 0
const turnZero = (i: number, j: number) => {
if (
i < 0 || i >= m ||
j < 0 || j >= n ||
grid[i][j] === '0'
) return
grid[i][j] = '0'
d.forEach(([dx, dy]) => turnZero(dx + i, dy + j))
}
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (grid[i][j] === '1') {
count++
turnZero(i, j)
}
}
}
return count
}
function numIslands(grid: string[][]): number {
const m = grid.length
const n = grid[0].length
const d = [[0, 1], [1, 0], [0, -1], [-1, 0]]
let count = 0
const turnZero = (i: number, j: number) => {
if (
i < 0 || i >= m ||
j < 0 || j >= n ||
grid[i][j] === '0'
) return
grid[i][j] = '0'
d.forEach(([dx, dy]) => turnZero(dx + i, dy + j))
}
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (grid[i][j] === '1') {
count++
turnZero(i, j)
}
}
}
return count
}
day10
斐波那契数
https://leetcode.cn/problems/fibonacci-number/
function fib(n: number): number {
if (n < 2) return n
return fib(n - 1) + fib(n - 2)
}
function fib(n: number): number {
if (n < 2) return n
return fib(n - 1) + fib(n - 2)
}
function fib(n: number): number {
return helper(n, [])
}
function helper(n: number, memo: number[]) {
if (n < 2) return n
if (!memo[n]) {
memo[n] = helper(n - 1, memo) + helper(n - 2, memo)
}
return memo[n]
}
function fib(n: number): number {
return helper(n, [])
}
function helper(n: number, memo: number[]) {
if (n < 2) return n
if (!memo[n]) {
memo[n] = helper(n - 1, memo) + helper(n - 2, memo)
}
return memo[n]
}
function fib(n: number): number {
if (n < 2) return n
const dp = [0, 1]
for (let i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2]
}
return dp[n]
}
function fib(n: number): number {
if (n < 2) return n
const dp = [0, 1]
for (let i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2]
}
return dp[n]
}
function fib(n: number): number {
if (n < 2) return n
let n1 = 0
let n2 = 1
let result: number
for (let i = 2; i <= n; i++) {
result = n1 + n2
n1 = n2
n2 = result
}
return n2
}
function fib(n: number): number {
if (n < 2) return n
let n1 = 0
let n2 = 1
let result: number
for (let i = 2; i <= n; i++) {
result = n1 + n2
n1 = n2
n2 = result
}
return n2
}
爬楼梯
https://leetcode.cn/problems/climbing-stairs/
function climbStairs(n: number): number {
return helper(n, [])
}
function helper (n: number, memo: number[]) {
if (n <= 2) return n
if (!memo[n]) {
memo[n] = helper(n - 1, memo) + helper(n - 2, memo)
}
return memo[n]
}
function climbStairs(n: number): number {
return helper(n, [])
}
function helper (n: number, memo: number[]) {
if (n <= 2) return n
if (!memo[n]) {
memo[n] = helper(n - 1, memo) + helper(n - 2, memo)
}
return memo[n]
}
function climbStairs(n: number): number {
if (n <= 2) return n
const dp = [1, 1]
for (let i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2]
}
return dp[n]
}
function climbStairs(n: number): number {
if (n <= 2) return n
const dp = [1, 1]
for (let i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2]
}
return dp[n]
}
function climbStairs(n: number): number {
if (n <= 2) return n
let n1 = 1
let n2 = 1
let result: number
for (let i = 2; i <= n; i++) {
result = n1 + n2
n1 = n2
n2 = result
}
return n2
}
function climbStairs(n: number): number {
if (n <= 2) return n
let n1 = 1
let n2 = 1
let result: number
for (let i = 2; i <= n; i++) {
result = n1 + n2
n1 = n2
n2 = result
}
return n2
}
day11
使用最小花费爬楼梯
https://leetcode.cn/problems/min-cost-climbing-stairs/
function minCostClimbingStairs(cost: number[]): number {
const n = cost.length
let n1 = 0
let n2 = 0
let result: number
for (let i = 2; i <= n; i++) {
result = Math.min(n2 + cost[i - 1], n1 + cost[i - 2])
n1 = n2
n2 = result
}
return n2
}
function minCostClimbingStairs(cost: number[]): number {
const n = cost.length
let n1 = 0
let n2 = 0
let result: number
for (let i = 2; i <= n; i++) {
result = Math.min(n2 + cost[i - 1], n1 + cost[i - 2])
n1 = n2
n2 = result
}
return n2
}
不同路径
https://leetcode.cn/problems/unique-paths/
function uniquePaths(m: number, n: number): number {
const dp = Array.from({ length: m }, () => new Array(n).fill(0))
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (i == 0 || j == 0) {
dp[i][j] = 1;
} else {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
}
}
}
return dp[m - 1][n - 1]
}
function uniquePaths(m: number, n: number): number {
const dp = Array.from({ length: m }, () => new Array(n).fill(0))
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (i == 0 || j == 0) {
dp[i][j] = 1;
} else {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
}
}
}
return dp[m - 1][n - 1]
}
day12
找到字符串中所有字母异位词
https://leetcode.cn/problems/find-all-anagrams-in-a-string/
function findAnagrams(s: string, p: string): number[] {
const sLen = s.length
const pLen = p.length
if (sLen < pLen) return []
const ans = []
const sCount = new Array(26).fill(0)
const pCount = new Array(26).fill(0)
for (let i = 0; i < pLen; i++) {
sCount[helper(s[i])]++
pCount[helper(p[i])]++
}
if (isEqual(sCount, pCount)) ans.push(0)
for (let i = 0; i < sLen - pLen; i++) {
sCount[helper(s[i])]--
sCount[helper(s[i + pLen])]++
if (isEqual(sCount, pCount)) ans.push(i + 1)
}
return ans
}
function isEqual(sCount: number[], pCount: number[]) {
if (sCount.toString() === pCount.toString()) return true
}
function helper(char: string) {
return char.charCodeAt(0) - 'a'.charCodeAt(0)
}
function findAnagrams(s: string, p: string): number[] {
const sLen = s.length
const pLen = p.length
if (sLen < pLen) return []
const ans = []
const sCount = new Array(26).fill(0)
const pCount = new Array(26).fill(0)
for (let i = 0; i < pLen; i++) {
sCount[helper(s[i])]++
pCount[helper(p[i])]++
}
if (isEqual(sCount, pCount)) ans.push(0)
for (let i = 0; i < sLen - pLen; i++) {
sCount[helper(s[i])]--
sCount[helper(s[i + pLen])]++
if (isEqual(sCount, pCount)) ans.push(i + 1)
}
return ans
}
function isEqual(sCount: number[], pCount: number[]) {
if (sCount.toString() === pCount.toString()) return true
}
function helper(char: string) {
return char.charCodeAt(0) - 'a'.charCodeAt(0)
}
替换后的最长重复字符
https://leetcode.cn/problems/longest-repeating-character-replacement/
function characterReplacement(s: string, k: number): number {
const nums = new Array(26).fill(0)
const n = s.length
let left = 0
let right = 0
let max = 0
while (right < n) {
nums[helper(s[right])]++
max = Math.max(max, nums[helper(s[right])])
if (right - left + 1 - max > k) {
nums[helper(s[left])]--
left++
}
right++
}
return right - left
}
function helper(char: string) {
return char.charCodeAt(0) - 'A'.charCodeAt(0)
}
function characterReplacement(s: string, k: number): number {
const nums = new Array(26).fill(0)
const n = s.length
let left = 0
let right = 0
let max = 0
while (right < n) {
nums[helper(s[right])]++
max = Math.max(max, nums[helper(s[right])])
if (right - left + 1 - max > k) {
nums[helper(s[left])]--
left++
}
right++
}
return right - left
}
function helper(char: string) {
return char.charCodeAt(0) - 'A'.charCodeAt(0)
}
day13
两数之和
https://leetcode.cn/problems/two-sum/
function twoSum(nums: number[], target: number): number[] {
const cached = new Map()
const len = nums.length
let curr: number
for (let i = 0; i < len; i++) {
curr = target - nums[i]
if (cached.has(curr)) {
return [cached.get(curr), i]
}
cached.set(nums[i], i)
}
return []
}
function twoSum(nums: number[], target: number): number[] {
const cached = new Map()
const len = nums.length
let curr: number
for (let i = 0; i < len; i++) {
curr = target - nums[i]
if (cached.has(curr)) {
return [cached.get(curr), i]
}
cached.set(nums[i], i)
}
return []
}
猜数字游戏
https://leetcode.cn/problems/bulls-and-cows/
function getHint(secret: string, guess: string): string {
const s = new Array(10).fill(0)
const g = new Array(10).fill(0)
let bulls = 0
for (let i = 0; i < secret.length; i++) {
if (secret[i] == guess[i]) {
bulls++
} else {
s[helper(secret[i])]++
g[helper(guess[i])]++
}
}
let cows = 0
for (let i = 0; i < 10; i++) {
cows += Math.min(s[i], g[i])
}
return `${ bulls }A${ cows }B`
}
function helper(char: string) {
return char.charCodeAt(0) - '0'.charCodeAt(0)
}
function getHint(secret: string, guess: string): string {
const s = new Array(10).fill(0)
const g = new Array(10).fill(0)
let bulls = 0
for (let i = 0; i < secret.length; i++) {
if (secret[i] == guess[i]) {
bulls++
} else {
s[helper(secret[i])]++
g[helper(guess[i])]++
}
}
let cows = 0
for (let i = 0; i < 10; i++) {
cows += Math.min(s[i], g[i])
}
return `${ bulls }A${ cows }B`
}
function helper(char: string) {
return char.charCodeAt(0) - '0'.charCodeAt(0)
}
day14
比较含退格的字符串
function backspaceCompare(s: string, t: string): boolean {
return helper(s) === helper(t)
}
function helper(str: string) {
const stack = []
for (let i = 0; i < str.length; i++) {
if (str[i] == '#') {
stack.pop()
} else {
stack.push(str[i])
}
}
return stack.join('')
}
function backspaceCompare(s: string, t: string): boolean {
return helper(s) === helper(t)
}
function helper(str: string) {
const stack = []
for (let i = 0; i < str.length; i++) {
if (str[i] == '#') {
stack.pop()
} else {
stack.push(str[i])
}
}
return stack.join('')
}
function backspaceCompare(s: string, t: string): boolean {
let i = s.length - 1
let j = t.length - 1
let skip: number
while (i >= 0 || j >= 0) {
skip = 0
while (i >= 0) {
if (s[i] === '#') {
skip++
i--
} else if (skip > 0){
skip--
i--
} else {
break
}
}
skip = 0
while (j >= 0) {
if (t[j] === '#') {
skip++
j--
} else if (skip > 0){
skip--
j--
} else {
break
}
}
if (s[i] !== t[j]) return false
i--
j--
}
return true
}
function backspaceCompare(s: string, t: string): boolean {
let i = s.length - 1
let j = t.length - 1
let skip: number
while (i >= 0 || j >= 0) {
skip = 0
while (i >= 0) {
if (s[i] === '#') {
skip++
i--
} else if (skip > 0){
skip--
i--
} else {
break
}
}
skip = 0
while (j >= 0) {
if (t[j] === '#') {
skip++
j--
} else if (skip > 0){
skip--
j--
} else {
break
}
}
if (s[i] !== t[j]) return false
i--
j--
}
return true
}
字符串解码
https://leetcode.cn/problems/decode-string/
function decodeString(s: string): string {
const stack = []
let str = ''
let count = ''
for (const char of s) {
if (char === '[') {
stack.push('[')
} else if (char === ']') {
while(true) {
const temp = stack.pop()
if (temp === '[') break
str = temp + str
}
while (true) {
const temp = stack.pop()
if (isNaN(+temp)) {
stack.push(temp)
break
}
count = temp + count
}
stack.push(str.repeat(+count))
str = ''
count = ''
} else {
stack.push(char)
}
}
return stack.join('')
}
function decodeString(s: string): string {
const stack = []
let str = ''
let count = ''
for (const char of s) {
if (char === '[') {
stack.push('[')
} else if (char === ']') {
while(true) {
const temp = stack.pop()
if (temp === '[') break
str = temp + str
}
while (true) {
const temp = stack.pop()
if (isNaN(+temp)) {
stack.push(temp)
break
}
count = temp + count
}
stack.push(str.repeat(+count))
str = ''
count = ''
} else {
stack.push(char)
}
}
return stack.join('')
}
day15
最后一块石头的重量
https://leetcode.cn/problems/last-stone-weight/
function lastStoneWeight(stones: number[]): number {
stones.sort((a, b) => b - a)
const insert = (num: number): void => {
let left = 0
let right = stones.length - 1
while (left <= right) {
const mid = left + Math.floor((right - left) / 2)
if (stones[mid] > num) {
left = mid + 1
} else {
right = mid - 1
}
}
stones.splice(right + 1, 0, num)
}
while (stones.length > 1) {
const m = stones.shift()
const n = stones.shift()
if (m === n) continue
insert(Math.abs(m - n))
}
return stones.length > 0 ? stones[0] : 0
}
function lastStoneWeight(stones: number[]): number {
stones.sort((a, b) => b - a)
const insert = (num: number): void => {
let left = 0
let right = stones.length - 1
while (left <= right) {
const mid = left + Math.floor((right - left) / 2)
if (stones[mid] > num) {
left = mid + 1
} else {
right = mid - 1
}
}
stones.splice(right + 1, 0, num)
}
while (stones.length > 1) {
const m = stones.shift()
const n = stones.shift()
if (m === n) continue
insert(Math.abs(m - n))
}
return stones.length > 0 ? stones[0] : 0
}
function lastStoneWeight(stones: number[]): number {
const heap = new BinaryHeap<number>((a, b) => b - a)
for (const stone of stones) {
heap.insert(stone)
}
while (heap.size() > 1) {
const a = heap.pop()
const b = heap.pop()
if (a > b) {
heap.insert(a - b)
}
}
return heap.size() ? heap.pop() : 0
}
type Compare<T> = (...args: T[]) => number
class BinaryHeap<T> {
data:T[]
compare: Compare<T>
constructor (compare: Compare<T>) {
this.data = [];
this.compare = compare;
}
private swap (i1: number, i2: number) {
[this.data[i1], this.data[i2]] = [this.data[i2], this.data[i1]];
}
private getParentIndex (i: number) {
return (i - 1) >> 1;
}
private getLeftIndex (i: number) {
return i * 2 + 1;
}
private getRightIndex (i: number) {
return i * 2 + 2;
}
private heapifyUp (curIdx: number) {
if (curIdx == 0) return;
const parentIdx = this.getParentIndex(curIdx);
if (this.data[parentIdx] && this.compare(this.data[curIdx], this.data[parentIdx]) < 0) {
this.swap(parentIdx, curIdx);
this.heapifyUp(parentIdx);
}
}
private heapifyDown (curIdx: number) {
const leftIdx = this.getLeftIndex(curIdx),
rightIdx = this.getRightIndex(curIdx);
if (this.data[leftIdx] && this.compare(this.data[leftIdx], this.data[curIdx]) < 0) {
this.swap(leftIdx, curIdx);
this.heapifyDown(leftIdx);
}
if (this.data[rightIdx] && this.compare(this.data[rightIdx], this.data[curIdx]) < 0) {
this.swap(rightIdx, curIdx);
this.heapifyDown(rightIdx);
}
}
insert (val: T) {
this.data.push(val);
this.heapifyUp(this.size() - 1);
}
pop () {
const ret = this.data[0]
const value = this.data.pop()
if (this.size()) {
this.data[0] = value;
this.heapifyDown(0);
}
return ret
}
peek () {
return this.data[0];
}
size () {
return this.data.length;
}
}
function lastStoneWeight(stones: number[]): number {
const heap = new BinaryHeap<number>((a, b) => b - a)
for (const stone of stones) {
heap.insert(stone)
}
while (heap.size() > 1) {
const a = heap.pop()
const b = heap.pop()
if (a > b) {
heap.insert(a - b)
}
}
return heap.size() ? heap.pop() : 0
}
type Compare<T> = (...args: T[]) => number
class BinaryHeap<T> {
data:T[]
compare: Compare<T>
constructor (compare: Compare<T>) {
this.data = [];
this.compare = compare;
}
private swap (i1: number, i2: number) {
[this.data[i1], this.data[i2]] = [this.data[i2], this.data[i1]];
}
private getParentIndex (i: number) {
return (i - 1) >> 1;
}
private getLeftIndex (i: number) {
return i * 2 + 1;
}
private getRightIndex (i: number) {
return i * 2 + 2;
}
private heapifyUp (curIdx: number) {
if (curIdx == 0) return;
const parentIdx = this.getParentIndex(curIdx);
if (this.data[parentIdx] && this.compare(this.data[curIdx], this.data[parentIdx]) < 0) {
this.swap(parentIdx, curIdx);
this.heapifyUp(parentIdx);
}
}
private heapifyDown (curIdx: number) {
const leftIdx = this.getLeftIndex(curIdx),
rightIdx = this.getRightIndex(curIdx);
if (this.data[leftIdx] && this.compare(this.data[leftIdx], this.data[curIdx]) < 0) {
this.swap(leftIdx, curIdx);
this.heapifyDown(leftIdx);
}
if (this.data[rightIdx] && this.compare(this.data[rightIdx], this.data[curIdx]) < 0) {
this.swap(rightIdx, curIdx);
this.heapifyDown(rightIdx);
}
}
insert (val: T) {
this.data.push(val);
this.heapifyUp(this.size() - 1);
}
pop () {
const ret = this.data[0]
const value = this.data.pop()
if (this.size()) {
this.data[0] = value;
this.heapifyDown(0);
}
return ret
}
peek () {
return this.data[0];
}
size () {
return this.data.length;
}
}
前K个高频单词
https://leetcode.cn/problems/top-k-frequent-words/
function topKFrequent(words: string[], k: number): string[] {
const cnt = new Map<string, number>()
for (const word of words) {
cnt.set(word, (cnt.get(word) || 0) + 1)
}
const rec: string[] = []
for (const entry of cnt.keys()) {
rec.push(entry)
}
rec.sort((a, b) => {
if (cnt.get(a) === cnt.get(b)) {
return a.localeCompare(b)
}
return cnt.get(b) - cnt.get(a)
})
return rec.slice(0, k)
}
function topKFrequent(words: string[], k: number): string[] {
const cnt = new Map<string, number>()
for (const word of words) {
cnt.set(word, (cnt.get(word) || 0) + 1)
}
const rec: string[] = []
for (const entry of cnt.keys()) {
rec.push(entry)
}
rec.sort((a, b) => {
if (cnt.get(a) === cnt.get(b)) {
return a.localeCompare(b)
}
return cnt.get(b) - cnt.get(a)
})
return rec.slice(0, k)
}