var twoSum = function (nums, target) {
const hash = {}
const n = nums.length
for (let i = 0; i < n; i++) {
const x = nums[i]
if (hash[x] !== undefined) {
return [hash[x], i]
}
hash[target - x] = i
}
return []
}
var addTwoNumbers = function (l1, l2) {
let head = new ListNode(-1)
let cur = head
let carry = 0
while (l1 || l2 || carry) {
let sum = carry
if (l1) {
sum += l1.val
l1 = l1.next
}
if (l2) {
sum += l2.val
l2 = l2.next
}
carry = parseInt(sum / 10)
sum %= 10
cur.next = new ListNode(sum)
cur = cur.next
}
return head.next
}
var trap = function (height) {
let l = 0
let r = height.length - 1
let lHeight = 0
let rHeight = 0
let ans = 0
while (l < r) {
if (height[l] < height[r]) {
lHeight = Math.max(lHeight, height[l])
ans += lHeight - height[l]
l++
} else {
rHeight = Math.max(rHeight, height[r])
ans += rHeight - height[r]
r--
}
}
return ans
}
var trap = function (height) {
let ans = 0
const stack = []
for (let i = 0; i < height.length; i++) {
while (stack.length && height[stack[stack.length - 1]] < height[i]) {
const k = stack.pop()
if (!stack.length) break
const j = stack[stack.length - 1]
const w = i - j - 1
const h = Math.min(height[j], height[i]) - height[k]
ans += h * w
}
stack.push(i)
}
return ans
}
var lengthOfLongestSubstring = function (s) {
let set = new Set()
let i = 0
let j = 0
let max = 0
const n = s.length
while (i < n) {
const ch = s[i]
while (set.has(ch)) {
set.delete(s[j])
j++
}
set.add(ch)
max = Math.max(max, set.size)
i++
}
return max
}
var findMedianSortedArrays = function (nums1, nums2) {
let n = nums1.length
let m = nums2.length
let len = n + m
let mid = len >> 1
let left = 0
let right = 0
let l = len % 2 === 0 ? mid - 1 : mid
let r = mid
let p1 = 0
let p2 = 0
let i = 0
const check = (ans) => {
if (i === l) {
left = ans
}
if (i === r) {
right = ans
}
i++
}
while (p1 < n && p2 < m && i <= r) {
check(nums1[p1] < nums2[p2] ? nums1[p1++] : nums2[p2++])
}
while (p1 < n && i <= r) {
check(nums1[p1++])
}
while (p2 < m && i <= r) {
check(nums2[p2++])
}
return len % 2 ? left : (left + right) / 2
}
function Node(k, v, l, r) {
this.l = l
this.r = r
this.k = k
this.v = v
}
var LRUCache = function (capacity) {
this.size = capacity
this.map = new Map()
this.head = new Node(-1, -1)
this.tail = new Node(-1, -1)
this.head.r = this.tail
this.tail.l = this.head
}
LRUCache.prototype.get = function (key) {
const node = this.map.get(key)
if (!node) return -1
this.update(node)
return node.v
}
LRUCache.prototype.update = function (node) {
this.delete(node)
node.r = this.head.r
node.l = this.head
this.head.r.l = node
this.head.r = node
}
LRUCache.prototype.delete = function (node) {
if (node.l) {
let l = node.l
l.r = node.r
node.r.l = l
}
}
LRUCache.prototype.put = function (key, value) {
const node = this.map.get(key) || new Node(key, value)
node.v = value
this.map.set(key, node)
this.update(node)
if (this.map.size > this.size) {
let del = this.tail.l
this.map.delete(del.k)
this.delete(del)
}
}
var reverseKGroup = function(head, k) {
const p = new ListNode(-1)
p.next = head
let prev = p
while(head){
let tail = prev
for(let i = 0; i < k; i++){
tail = tail.next
if(!tail) return p.next
}
const next = tail.next;
[head, tail] = reverse(head, tail)
prev.next = head
tail.next = next
prev = tail
head = tail.next
}
return p.next
};
var reverse = (head, tail) => {
let prev = tail.next
let p = head
while(prev !== tail){
const next = p.next
p.next = prev
prev = p
p = next
}
return [tail, head]
}
var longestPalindrome = function (s) {
let start = 0
let end = 0
const n = s.length
for (let i = 0; i < n; i++) {
const len1 = expand(s, i, i)
const len2 = expand(s, i, i + 1)
const len = Math.max(len1, len2)
if (len > end - start) {
start = i - Math.floor((len - 1) / 2)
end = i + Math.floor(len / 2)
}
}
return s.substring(start, end + 1)
}
const expand = (s, l, r) => {
while (l >= 0 && r < s.length && s[l] === s[r]) {
l--
r++
}
return r - l - 1
}
var reverseList = function(head) {
let prev = null
while(head){
const next = head.next
head.next = prev
prev = head
head = next
}
return prev
};
var reverse = function (x) {
let res = 0
while (x !== 0) {
res = res * 10 + (x % 10)
x = ~~(x / 10)
if (res < Math.pow(-2, 31) || res > Math.pow(2, 31) - 1) {
return 0
}
}
return res
}
var threeSum = function (nums) {
let n = nums.length
const res = []
if (n < 2) return res
nums.sort((a, b) => a - b)
for (let i = 0; i < n - 2; i++) {
const a = nums[i]
if (a > 0) break
if (i > 0 && a === nums[i - 1]) continue
let l = i + 1
let r = n - 1
while (l < r) {
const b = nums[l]
const c = nums[r]
const sum = a + b + c
if (sum === 0) {
res.push([a, b, c])
while (l < r && b === nums[l + 1]) {
l++
}
while (l < r && c === nums[r - 1]) {
r--
}
l++
r--
} else if (sum > 0) {
r--
} else {
l++
}
}
}
return res
}
var findKthNumber = function (n, k) {
let curr = 1
k--
while (k > 0) {
const m = getMid(curr, n)
if (m <= k) {
k -= m
curr++
} else {
curr = curr * 10
k--
}
}
return curr
}
var getMid = function (curr, n) {
let m = 0
let fast = curr
let slow = curr
while (fast <= n) {
m += Math.min(slow, n) - fast + 1
fast = fast * 10
slow = slow * 10 + 9
}
return m
}
var maxSubArray = function (nums) {
const n = nums.length
let pre = nums[0]
let max = pre
for (let i = 1; i < n; i++) {
pre = Math.max(nums[i], pre + nums[i])
max = Math.max(max, pre)
}
return max
}
var maxArea = function (height) {
let l = 0
let r = height.length - 1
let max = 0
while (l < r) {
max = Math.max(Math.min(height[l], height[r]) * (r - l), max)
if (height[l] < height[r]) l++
else r--
}
return max
}
var maxPathSum = function (root) {
let max = Number.MIN_SAFE_INTEGER
const dfs = (node) => {
if (!node) return 0
const l = Math.max(dfs(node.left), 0)
const r = Math.max(dfs(node.right), 0)
const val = l + r + node.val
max = Math.max(val, max)
return node.val + Math.max(l, r)
}
dfs(root)
return max
}
var mergeKLists = function (lists) {
if (!lists.length) return null
return toSortList(lists)
}
var toSortList = function (list) {
if (list.length <= 1) return list[0]
const mid = list.length >> 1
return marge(mergeKLists(list.slice(0, mid)), mergeKLists(list.slice(mid)))
}
var marge = function (l1, l2) {
if (!l1 && !l2) return null
if (!l1 || !l2) return l1 || l2
let curr = (head = new ListNode(null))
while (l1 && l2) {
if (l1.val < l2.val) {
curr.next = l1
l1 = l1.next
} else {
curr.next = l2
l2 = l2.next
}
curr = curr.next
}
curr.next = l1 || l2
return head.next
}
var search = function (nums, target) {
let l = 0
let r = nums.length - 1
while (l <= r) {
let m = l + Math.floor((r - l) / 2)
if (nums[m] === target) return m
if (nums[l] <= nums[m]) {
if (nums[l] <= target && target < nums[m]) {
r = m - 1
} else {
l = m + 1
}
} else {
if (nums[m] < target && target <= nums[r]) {
l = m + 1
} else {
r = m - 1
}
}
}
return -1
}
var nextPermutation = function (nums) {
let i = nums.length - 2
while (i >= 0 && nums[i] >= nums[i + 1]) {
i--
}
if (i >= 0) {
let j = nums.length - 1
while (j >= 0 && nums[i] >= nums[j]) {
j--
}
swap(nums, i, j)
}
let l = i + 1
let r = nums.length - 1
while (l < r) {
swap(nums, l++, r--)
}
}
function swap(nums, i, j) {
let temp = nums[i]
nums[i] = nums[j]
nums[j] = temp
}
var merge = function (intervals) {
intervals.sort((a, b) => a[0] - b[0])
const n = intervals.length
const res = []
for (let i = 0; i < n; i++) {
const l = intervals[i][0]
const r = intervals[i][1]
if (!res.length || res[res.length - 1][1] < l) {
res.push([l, r])
} else {
res[res.length - 1][1] = Math.max(res[res.length - 1][1], r)
}
}
return res
}
var candy = function (ratings) {
const n = ratings.length
const l = new Array(n).fill(1)
const r = new Array(n).fill(1)
for (let i = 1; i < n; i++) {
if (ratings[i] > ratings[i - 1]) l[i] = l[i - 1] + 1
}
let count = l[n - 1]
for (let i = n - 2; i >= 0; i--) {
if (ratings[i] > ratings[i + 1]) r[i] = r[i + 1] + 1
count += Math.max(l[i], r[i])
}
return count
}
var reverseBetween = function (head, left, right) {
const dummy = new ListNode()
dummy.next = head
let p = dummy
let k = left - 1
while (k--) p = p.next
let front = p
let pre = p.next
let frontNode = pre
let cur = pre.next
k = right - left
while (k--) {
let next = cur.next
cur.next = pre
pre = cur
cur = next
}
front.next = pre
frontNode.next = cur
return dummy.next
}
var maxProfit = function (prices) {
const n = prices.length
if (n < 2) return 0
const dp = new Array(n).fill(0).map(() => new Array(2).fill(0))
dp[0][0] = 0
dp[0][1] = -prices[0]
for (let i = 1; i < n; i++) {
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i])
dp[i][1] = Math.max(dp[i - 1][1], -prices[i])
}
return dp[n - 1][0]
}
var maxProfit = function (prices) {
const n = prices.length
let max = 0
let min = Infinity
for (let i = 0; i < n; i++) {
min = Math.min(min, prices[i])
max = Math.max(max, prices[i] - min)
}
return max
}
var mergeTwoLists = function (l1, l2) {
let head = new ListNode(null)
let curr = head
while (l1 && l2) {
if (l1.val < l2.val) {
curr.next = l1
l1 = l1.next
} else {
curr.next = l2
l2 = l2.next
}
curr = curr.next
}
curr.next = !l1 ? l2 : l1
return head.next
}
var rightSideView = function (root) {
if (!root) return []
const q = [root]
const result = []
while (q.length) {
const len = q.length
let node = null
for (let i = 0; i < len; i++) {
node = q.shift()
if (node.left) q.push(node.left)
if (node.right) q.push(node.right)
}
result.push(node.val)
}
return result
}
var findKthLargest = function (nums, k) {
return findK(nums, 0, nums.length - 1, nums.length - k)
}
var findK = function (nums, p, q, k) {
if (p >= q) return nums[k]
const m = partition(nums, p, q)
return m > k ? findK(nums, p, m - 1, k) : findK(nums, m + 1, q, k)
}
var partition = function (nums, p, q) {
const x = nums[p]
let i = p + 1
let j = q
while (i < j) {
while (i < j && nums[i] <= x) i++
while (i < j && nums[j] >= x) j--
swap(nums, i, j)
}
if (nums[j] >= x) j--
swap(nums, j, p)
return j
}
var swap = function (nums, i, j) {
const tem = nums[i]
nums[i] = nums[j]
nums[j] = tem
}
var climbStairs = function (n) {
const dp = []
dp[0] = 0
dp[1] = 1
dp[2] = 2
for (let i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2]
}
return dp[n]
}
var climbStairs = function (n) {
let one = 1
let two = 1
for (let i = 2; i <= n; i++) {
let temp = one + two
one = two
two = temp
}
return two
}
var reorderList = function (head) {
let fast = head
let slow = head
while (fast.next && fast.next.next) {
fast = fast.next.next
slow = slow.next
}
let midHead = slow.next
slow.next = null
const s = []
while (midHead) {
s.push(midHead)
const next = midHead.next
midHead.next = null
midHead = next
}
let cur = head
while (cur) {
const next = cur.next
cur.next = s.pop() || null
if (!cur.next) break
cur.next.next = next
cur = next
}
return head
}
var reorderList = function (head) {
let fast = head
let slow = head
while (fast.next && fast.next.next) {
fast = fast.next.next
slow = slow.next
}
let p1 = head
let p2 = reserve(slow.next)
slow.next = null
while (p2) {
let n1 = p1.next
let n2 = p2.next
p1.next = p2
p2.next = n1
p1 = n1
p2 = n2
}
return head
function reserve(head) {
let prev = null
while (head) {
const next = head.next
head.next = prev
prev = head
head = next
}
return prev
}
}
var zigzagLevelOrder = function (root) {
const result = []
if (!root) return result
const stack = [root]
let flag = true
while (stack.length) {
const res = []
const len = stack.length
for (let i = 0; i < len; i++) {
const node = stack.shift()
res.push(node.val)
if (node.left) stack.push(node.left)
if (node.right) stack.push(node.right)
}
if (!flag) res.reverse()
flag = !flag
result.push(res)
}
return result
}
var permute = function (nums) {
const res = []
const vis = {}
const dfs = (t) => {
if (t.length === nums.length) return res.push(t)
for (const x of nums) {
if (vis[x]) continue
vis[x] = true
t.push(x)
dfs(t.slice())
t.pop()
vis[x] = false
}
}
dfs([])
return res
}
var longestValidParentheses = function (s) {
const stack = [-1]
const n = s.length
let max = 0
for (let i = 0; i < n; i++) {
const c = s[i]
if (c === '(') {
stack.push(i)
} else {
stack.pop()
if (stack.length <= 0) {
stack.push(i)
} else {
max = Math.max(max, i - stack[stack.length - 1])
}
}
}
return max
}
var longestValidParentheses = function (s) {
let max = 0
const n = s.length
const dp = new Array(n).fill(0)
for (let i = 1; i < n; i++) {
if (s[i] === ')') {
if (s[i - 1] === '(') {
dp[i] = (dp[i - 2] || 0) + 2
} else if (i - dp[i - 1] > 0 && s[i - dp[i - 1] - 1] === '(') {
dp[i] = dp[i - 1] + (i - dp[i - 1] >= 2 ? dp[i - dp[i - 1] - 2] : 0) + 2
}
max = Math.max(dp[i], max)
}
}
return max
}
var spiralOrder = function (matrix) {
const res = []
const m = matrix.length
const n = matrix[0].length
const total = n * m
let t = 0
let b = m - 1
let l = 0
let r = n - 1
while (res.length < total) {
for (let i = l; i <= r; i++) res.push(matrix[t][i])
t++
for (let i = t; i <= b; i++) res.push(matrix[i][r])
r--
if (res.length >= total) break
for (let i = r; i >= l; i--) res.push(matrix[b][i])
b--
for (let i = b; i >= t; i--) res.push(matrix[i][l])
l++
}
return res
}
var isMatch = function (s, p) {
const m = s.length
const n = p.length
const dp = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(false))
dp[0][0] = true
for (let j = 1; j <= n; j++) {
if (p[j - 1] === '*') dp[0][j] = dp[0][j - 2]
}
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
if (s[i - 1] === p[j - 1] || p[j - 1] === '.') {
dp[i][j] = dp[i - 1][j - 1]
} else if (p[j - 1] === '*') {
if (s[i - 1] === p[j - 2] || p[j - 2] === '.') {
dp[i][j] = dp[i][j - 2] || dp[i - 1][j - 2] || dp[i - 1][j]
} else {
dp[i][j] = dp[i][j - 2]
}
}
}
}
return dp[m][n]
}
var generateParenthesis = function (n) {
const result = []
const dfs = (s, l, r) => {
if (l === 0 && r === 0) return result.push(s)
if (l > 0) dfs(s + '(', l - 1, r)
if (r > l) dfs(s + ')', l, r - 1)
}
dfs('', n, n)
return result
}
var sortList = function(head) {
return toSortList(head, null)
};
var toSortList = function(head, tail) {
if(!head) return head
if(head.next === tail){
head.next = null
return head
}
const mid = findMidNode(head, tail)
return marge(toSortList(head, mid), toSortList(mid, tail))
};
function marge(l1, l2){
const dummy = new ListNode(null)
let cur = dummy
while(l1 && l2){
if(l1.val < l2.val){
cur.next = l1
l1 = l1.next
}else{
cur.next = l2
l2 = l2.next
}
cur = cur.next
}
cur.next = l1 || l2
return dummy.next
}
var findMidNode = function(head, tail) {
let fast = head
let slow = head
while(fast && fast !== tail) {
slow = slow.next
fast = fast.next
if(fast && fast !== tail){
fast = fast.next
}
}
return slow
};
var buildTree = function (preorder, inorder) {
const map = new Map()
inorder.forEach((root, i) => map.set(root, i))
const n = preorder.length
const build = (pL, pR, iL, iR) => {
if (pL > pR) return null
const rootVal = preorder[pL]
const root = new TreeNode(rootVal)
const idx = map.get(rootVal)
const leftSize = idx - iL
root.left = build(pL + 1, pL + leftSize, iL, idx - 1)
root.right = build(pL + leftSize + 1, pR, idx + 1, iR)
return root
}
return build(0, n - 1, 0, n - 1)
}
var numIslands = function (grid) {
const dir = [
[-1, 0],
[0, -1],
[1, 0],
[0, 1],
]
const m = grid.length
const n = grid[0].length
let ans = 0
const dfs = (x, y) => {
grid[x][y] = 1
for (const [dx, dy] of dir) {
const a = x + dx
const b = y + dy
if (a >= 0 && b >= 0 && a < m && b < n) {
if (grid[a][b] === '1') {
dfs(a, b)
}
}
}
}
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (grid[i][j] === '1') {
ans++
dfs(i, j)
}
}
}
return ans
}
var restoreIpAddresses = function (s) {
const res = []
const n = s.length
const dfs = (t, start) => {
if (start >= n && t.length === 4) return res.push(t.join('.'))
if (t.length > 4) return
for (let i = start; i < n; i++) {
const str = s.slice(start, i + 1)
if (str.length >= 2 && str[0] === '0') return
if (str.length >= 3 && +str > 255) return
t.push(str)
dfs(t.slice(), i + 1)
t.pop()
}
}
dfs([], 0)
return res
}
var levelOrder = function (root) {
if (!root) return []
let res = []
let q = [root]
while (q.length) {
let result = []
let len = q.length
for (let i = 0; i < len; i++) {
let node = q.shift()
if (!node) continue
result.push(node.val)
if (node.left) q.push(node.left)
if (node.right) q.push(node.right)
}
res.push(result)
}
return res
}
var firstMissingPositive = function (nums) {
const n = nums.length
for (let i = 0; i < n; i++) {
if (nums[i] <= 0) {
nums[i] = n + 1
}
}
for (let i = 0; i < n; i++) {
let num = Math.abs(nums[i])
if (num <= n) {
nums[num - 1] = -Math.abs(nums[num - 1])
}
}
for (let i = 0; i < n; i++) {
if (nums[i] > 0) {
return i + 1
}
}
return n + 1
}
var isValid = function (s) {
if ((s.length & 1) == 1) return false
const hash = {
')': '(',
']': '[',
'}': '{',
}
const stack = []
for (let i = 0; i < s.length; i++) {
const ch = s[i]
const k = hash[ch]
if (k) {
if (stack.pop() !== k) return false
} else {
stack.push(ch)
}
}
return stack.length === 0
}
var longestCommonPrefix = function (strs) {
const n = strs.length
if (n === 1) return strs[0]
let min = strs[0].length
let T = strs[0]
let index = 0
for (let i = 1; i < n; i++) {
if (strs[i].length < min) {
min = strs[i].length
T = strs[i]
index = i
}
}
let s = ''
for (let i = 0; i < n; i++) {
if (i === index) continue
if (min === 0) return ''
let l = 0
let r = min
let str = strs[i]
s = ''
while (l < r && T[l] === str[l]) {
s += str[l]
l++
}
min = l
T = s
}
return s
}
var minDistance = function (word1, word2) {
const n = word1.length
const m = word2.length
const dp = new Array(n + 1).fill(0).map(() => new Array(m + 1).fill(0))
for (let i = 0; i <= n; i++) {
dp[i][0] = i
}
for (let i = 0; i <= m; i++) {
dp[0][i] = i
}
for (let i = 1; i <= n; i++) {
for (let j = 1; j <= m; j++) {
if (word1[i - 1] === word2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1]
} else {
dp[i][j] = Math.min(dp[i - 1][j], dp[i - 1][j - 1], dp[i][j - 1]) + 1
}
}
}
return dp[n][m]
}
var rob = function (nums) {
const dp = []
dp[0] = nums[0]
dp[1] = Math.max(nums[0], nums[1])
const n = nums.length
for (let i = 2; i < n; i++) {
dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1])
}
return dp[n - 1]
}
var rob = function (nums) {
const n = nums.length
if (n === 1) return nums[0]
let prev = nums[0]
let curr = Math.max(nums[0], nums[1])
for (let i = 2; i < n; i++) {
let temp = Math.max(prev + nums[i], curr)
prev = curr
curr = temp
}
return curr
}
var findRepeatNumber = function (nums) {
const n = nums.length
let i = 0
while (i < n) {
if (nums[i] === i) {
i++
} else {
if (nums[nums[i]] === nums[i]) return nums[i]
const temp = nums[i]
nums[i] = nums[nums[i]]
nums[temp] = temp
}
}
}
var MyQueue = function () {
this.enqueue = []
this.dequeue = []
}
MyQueue.prototype.push = function (x) {
this.enqueue.push(x)
}
MyQueue.prototype.pop = function () {
if (!this.dequeue.length) {
while (this.enqueue.length) {
this.dequeue.push(this.enqueue.pop())
}
}
return this.dequeue.pop()
}
MyQueue.prototype.peek = function () {
if (!this.dequeue.length) {
while (this.enqueue.length) {
this.dequeue.push(this.enqueue.pop())
}
}
return this.dequeue[this.dequeue.length - 1]
}
MyQueue.prototype.empty = function () {
return !this.dequeue.length && !this.enqueue.length
}
var merge = function (nums1, m, nums2, n) {
let pos1 = m - 1
let pos2 = n - 1
let pos = m + n - 1
while (pos1 >= 0 && pos2 >= 0) {
nums1[pos--] = nums1[pos1] > nums2[pos2] ? nums1[pos1--] : nums2[pos2--]
}
if (pos1 == -1) {
for (let i = 0; i < pos2 + 1; i++) {
nums1[i] = nums2[i]
}
}
return nums1
}
const table = [
[0, 1, 2, 3],
[3, 3, 2, 3],
[3, 3, 2, 3],
[3, 3, 3, 3],
]
const num = {
0: true,
1: true,
2: true,
3: true,
4: true,
5: true,
6: true,
7: true,
8: true,
9: true,
}
class AutoMata {
constructor() {
this.state = 0
this.sign = 1
this.ans = 0
this.max = Math.pow(2, 31) - 1
this.min = -Math.pow(2, 31)
}
gets(c) {
if (c == ' ') return 0
if (c == '+' || c == '-') return 1
if (num[c]) return 2
return 3
}
get(c) {
this.state = table[this.state][this.gets(c)]
if (this.state == 2) {
this.ans = this.ans * 10 + (c - 0)
this.ans =
this.sign == 1
? Math.min(this.ans, this.max)
: Math.min(this.ans, -this.min)
}
if (this.state == 1 && c == '-') this.sign = -1
}
}
const myAtoi = function (s) {
const autoMata = new AutoMata()
for (let i = 0; i < s.length; i++) {
autoMata.get(s[i])
}
return autoMata.ans * autoMata.sign
}
var longestConsecutive = function (nums) {
const n = nums.length
if (!n) return 0
const hash = {}
let max = 1
for (let i = 0; i < n; i++) hash[nums[i]] = true
for (let i = 0; i < n; i++) {
if (!hash[nums[i] - 1]) {
let curr = nums[i] + 1
let ans = 1
while (hash[curr]) {
ans++
curr++
}
max = Math.max(max, ans)
}
}
return max
}
var map = {
I: 1,
V: 5,
X: 10,
L: 50,
C: 100,
D: 500,
M: 1000,
}
var romanToInt = function (s) {
let last = 0
let curr = 0
for (let i = 0; i < s.length; i++) {
let num = map[s[i]]
if (num > last) {
curr -= last
} else {
curr += last
}
last = num
}
return curr + last
}
var swapPairs = function (head) {
const dummy = new ListNode(null, head)
let cur = dummy.next
let pre = dummy
while (cur && cur.next) {
let n = cur.next.next
pre.next = cur.next
cur.next = n
pre.next.next = cur
pre = cur
cur = n
}
return dummy.next
}
var swapPairs = function (head) {
if (!head || !head.next) return head
let p = head.next
head.next = swapPairs(p.next)
p.next = head
return p
}
var minWindow = function (s, t) {
let map = new Map()
let hash = {}
for (let ch of t) {
hash[ch] = 0
map.set(ch, (map.get(ch) || 0) + 1)
}
let l = 0
let r = -1
let check = () => {
for (let [ch, count] of map.entries()) {
if (hash[ch] < count) return false
}
return true
}
let len = Infinity
let start = -1
let end = -1
while (r < s.length) {
r++
if (hash[s[r]] !== undefined) {
hash[s[r]]++
}
while (l <= r && check()) {
if (r - l + 1 < len) {
len = r - l + 1
start = l
end = l + len
}
if (hash[s[l]]) {
hash[s[l]]--
}
l++
}
}
return s.substring(start, end)
}
var dailyTemperatures = function (T) {
const stack = []
const res = new Array(T.length).fill(0)
for (let i = 0; i < T.length; i++) {
while (stack.length && T[i] > T[stack[stack.length - 1]]) {
const idx = stack.pop()
res[idx] = i - idx
}
stack.push(i)
}
return res
}
var mySqrt = function (x) {
let left = 0
let right = Math.floor(x / 2) + 1
let ans = -1
while (left <= right) {
let mid = Math.floor((right + left) / 2)
let num = mid * mid
if (num < x) {
ans = mid
left = mid + 1
} else if (num > x) {
right = mid - 1
} else {
return mid
}
}
return ans
}
var maximalSquare = function (matrix) {
const m = matrix.length
const n = matrix[0].length
const dp = new Array(m).fill(0).map(() => new Array(n).fill(0))
let max = 0
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (matrix[i][j] === '1') {
if (i === 0 || j === 0) {
dp[i][j] = 1
} else {
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1
}
}
max = Math.max(dp[i][j], max)
}
}
return max * max
}
var isPalindrome = function (x) {
if (x < 0 || (x % 10 === 0 && x !== 0)) return false
let num = 0
while (x > num) {
let mod = x % 10
num = num * 10 + mod
x = Math.floor(x / 10)
}
return x === num || x === Math.floor(num / 10)
}
var jump = function (nums) {
let len = nums.length
let end = 0
let maxPosition = 0
let steps = 0
for (let i = 0; i < len - 1; i++) {
maxPosition = Math.max(maxPosition, i + nums[i])
if (i == end) {
end = maxPosition
steps++
}
}
return steps
}
var decodeString = function (s) {
let res = ''
for (let i = 0; i < s.length; ) {
if (isNaN(s[i])) {
res += s[i++]
} else {
let k = 0
while (!isNaN(s[i])) {
k = k * 10 + (s[i++] - 0)
}
let j = i + 1
let sum = 1
while (sum > 0) {
if (s[j] === '[') sum++
if (s[j] === ']') sum--
j++
}
const r = decodeString(s.substring(i + 1, j - 1))
while (k--) res += r
i = j
}
}
return res
}
var solveNQueens = function (n) {
let grid = new Array(n).fill(0).map(() => new Array(n).fill('.'))
let column = {}
let main = {}
let sub = {}
let path = []
let check = (x, y) => column[y] || main[x + y] || sub[x - y]
let dfs = (t) => {
if (t == n) {
path.push(grid.map((item) => item.join('')))
return
}
for (let i = 0; i < n; i++) {
if (check(t, i)) continue
grid[t][i] = 'Q'
column[i] = main[t + i] = sub[t - i] = true
dfs(t + 1)
column[i] = main[t + i] = sub[t - i] = false
grid[t][i] = '.'
}
}
dfs(0)
return path
}
var lengthOfLIS = function (nums) {
if (!nums.length) return 0
let dp = []
dp[0] = 1
let max = 1
for (let i = 1; i < nums.length; i++) {
dp[i] = 1
for (let j = 0; j < i; j++) {
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1)
}
}
max = Math.max(max, dp[i])
}
return max
}
var lengthOfLIS = function (nums) {
let tail = []
let res = 0
for (let num of nums) {
let i = 0,
j = res
while (i < j) {
let m = Math.floor((i + j) / 2)
if (num > tail[m]) i = m + 1
else j = m
}
tail[i] = num
if (j === res) res++
}
return res
}
var reversePairs = function (nums) {
if (!nums.length) return 0
return margeSort(nums, 0, nums.length - 1, [])
}
var margeSort = function (nums, l, r, result) {
if (l >= r) return 0
const m = (l + r) >> 1
const lCount = margeSort(nums, l, m, result)
const rCount = margeSort(nums, m + 1, r, result)
const count = marge(nums, l, r, result)
return count + lCount + rCount
}
var marge = function (nums, s, e, result) {
let res = 0
let e1 = (s + e) >> 1
let s2 = e1 + 1
let i1 = s
let i2 = s2
while (i1 <= e1 && i2 <= e) {
if (nums[i1] <= nums[i2]) {
result[i1 + i2 - s2] = nums[i1++]
} else {
result[i1 + i2 - s2] = nums[i2++]
res += e1 - i1 + 1
}
}
while (i1 <= e1) {
result[i1 + i2 - s2] = nums[i1++]
}
while (i2 <= e) {
result[i1 + i2 - s2] = nums[i2++]
}
while (s <= e) {
nums[s] = result[s++]
}
return res
}
var subsets = function (nums) {
let res = []
let numLen = nums.length
let dfs = (t, start) => {
res.push(t)
for (let i = start; i < numLen; i++) {
t.push(nums[i])
dfs(t.slice(), i + 1)
t.pop()
}
}
dfs([], 0)
return res
}
var subset = function (nums) {
let res = []
let n = nums.length
let b = 1 << n
for (let i = 0; i < b; i++) {
let now = []
for (let j = 0; j < n; j++) {
if ((i >> j) & 1) {
now.push(nums[j])
}
}
res.push(now)
}
return res
}
var exist = function (board, word) {
const m = board.length
const n = board[0].length
const dx = [-1, 0, 1, 0]
const dy = [0, 1, 0, -1]
const dfs = (x, y, len) => {
if (len === word.length) return true
const temp = board[x][y]
board[x][y] = '#'
for (let i = 0; i < 4; i++) {
const a = x + dx[i]
const b = y + dy[i]
if (a >= 0 && b >= 0 && a < m && b < n && board[a][b] === word[len]) {
if (dfs(a, b, len + 1)) return true
}
}
board[x][y] = temp
return false
}
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (board[i][j] === word[0]) {
if (dfs(i, j, 1)) return true
}
}
}
return false
}
var isSymmetric = function (root) {
return dfs(root.left, root.right)
}
var dfs = (left, right) => {
if (!left && !right) return true
if (!left || !right) return false
if (left.val != right.val) return false
return dfs(left.right, right.left) && dfs(left.left, right.right)
}
var isSymmetric = function (root) {
if (!root || (root.left == root.right && root.right == null)) return true
let q = [root.left, root.right]
while (q.length) {
let left = q.shift()
let right = q.shift()
if (!left && !right) continue
if (!left || !right) return false
if (left.val != right.val) return false
q.push(left.left, right.right)
q.push(left.right, right.left)
}
return true
}
var addStrings = function (num1, num2) {
let i = num1.length - 1
let j = num2.length - 1
let carry = 0
let res = ''
while (i >= 0 || j >= 0 || carry) {
let sum = carry
if (i >= 0) {
sum += +num1[i--]
}
if (j >= 0) {
sum += +num2[j--]
}
carry = Math.floor(sum / 10)
sum %= 10
res = sum + res
}
return res
}
var maxProfit = function (prices) {
const n = prices.length
const dp = new Array(n).fill(0).map(() => new Array(2).fill(0))
dp[0][0] = 0
dp[0][1] = -prices[0]
for (let i = 1; i < n; i++) {
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i])
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i])
}
return dp[n - 1][0]
}
var maxProfit = function (prices) {
const n = prices.length
let sell = 0
let buy = -prices[0]
for (let i = 1; i < n; i++) {
let s = Math.max(sell, buy + prices[i])
let b = Math.max(buy, sell - prices[i])
sell = s
buy = b
}
return sell
}
var maxProfit = function (prices) {
let profit = 0
for (let i = 1; i < prices.length; i++) {
let temp = prices[i] - prices[i - 1]
profit += temp > 0 ? temp : 0
}
return profit
}
var convert = function (s, numRows) {
if (numRows === 1) return s
let res = ''
const n = s.length
for (let j = 0; j < numRows; j++) {
if (j === 0 || j === numRows - 1) {
let i = j
while (i < n) {
res += s[i]
i += 2 * (numRows - 1)
}
} else {
let k = j
let i = numRows * 2 - 1 - j - 1
while (i < n || k < n) {
if (k < n) res += s[k]
if (i < n) res += s[i]
i += 2 * (numRows - 1)
k += 2 * (numRows - 1)
}
}
}
return res
}
var minArray = function (numbers) {
let l = 0
let r = numbers.length - 1
while (l < r) {
let m = l + ((r - l) >> 1)
if (numbers[m] > numbers[r]) {
l = m + 1
} else if (numbers[m] < numbers[r]) {
r = m
} else {
r--
}
}
return numbers[l]
}
var getIntersectionNode = function (headA, headB) {
let p1 = headA
let p2 = headB
while (p1 != p2) {
p1 = p1 == null ? headB : p1.next
p2 = p2 == null ? headA : p2.next
}
return p1
}
var diameterOfBinaryTree = function (root) {
let ans = 1
var depth = function (root) {
if (!root) return 0
let left = depth(root.left)
let right = depth(root.right)
ans = Math.max(ans, left + right + 1)
return Math.max(left, right) + 1
}
depth(root)
return ans - 1
}
var numTrees = function (n) {
const dp = new Array(n + 1).fill(0)
dp[0] = 1
dp[1] = 1
for (let i = 2; i <= n; i++) {
for (let j = 1; j <= i; j++) {
dp[i] += dp[j - 1] * dp[i - j]
}
}
return dp[n]
}
var lowestCommonAncestor = function (root, p, q) {
let ans
let dfs = (root, p, q) => {
if (root == null) return false
let left = dfs(root.left, p, q)
let right = dfs(root.right, p, q)
if (
(left && right) ||
((root.val == p.val || root.val == q.val) && (left || right))
) {
ans = root
}
return left || right || root.val == p.val || root.val == q.val
}
dfs(root, p, q)
return ans
}
var lowestCommonAncestor = function (root, p, q) {
if (!root || root == p || root == q) return root
let left = lowestCommonAncestor(root.left, p, q)
let right = lowestCommonAncestor(root.right, p, q)
if (!left && !right) return null
if (!left) return right
if (!right) return left
return root
}
var getKthFromEnd = function (head, k) {
if (k <= 0 || !head) return null
let fast = head
let slow = head
while (k--) {
fast = fast.next
}
while (fast) {
fast = fast.next
slow = slow.next
}
return slow
}
var minPathSum = function (grid) {
const m = grid.length
const n = grid[0].length
for (let i = 1; i < m; i++) {
grid[i][0] = grid[i - 1][0] + grid[i][0]
}
for (let i = 1; i < n; i++) {
grid[0][i] = grid[0][i - 1] + grid[0][i]
}
for (let i = 1; i < m; i++) {
for (let j = 1; j < n; j++) {
grid[i][j] = Math.min(grid[i - 1][j], grid[i][j - 1]) + grid[i][j]
}
}
return grid[m - 1][n - 1]
}
var maxDepth = function (root) {
if (!root) return 0
return 1 + Math.max(maxDepth(root.left), maxDepth(root.right))
}
var maxDepth = function (root) {
if (!root) return 0
let queue = [root]
let ans = 0
while (queue.length) {
let count = queue.length
while (count) {
let node = queue.shift()
if (node.left) queue.push(node.left)
if (node.right) queue.push(node.right)
count -= 1
}
ans += 1
}
return ans
}
var calculate = function (s) {
let ops = [1]
let sign = 1
let n = s.length
let i = 0
let res = 0
while (i < n) {
const ch = s[i]
if (ch == ' ') {
i++
} else if (ch == '+') {
sign = ops[ops.length - 1]
i++
} else if (ch == '-') {
sign = -ops[ops.length - 1]
i++
} else if (ch == '(') {
ops.push(sign)
i++
} else if (ch == ')') {
ops.pop()
i++
} else {
let num = 0
while (i < n && !isNaN(Number(s[i])) && s[i] != ' ') {
num = num * 10 + s[i].charCodeAt() - '0'.charCodeAt()
i++
}
res += sign * num
}
}
return res
}
var maxAreaOfIsland = function (grid) {
let dx = [-1, 0, 1, 0]
let dy = [0, 1, 0, -1]
let m = grid.length
let n = grid[0].length
let ans = 0
let dfs = (x, y) => {
grid[x][y] = 0
let res = 1
for (let i = 0; i < 4; i++) {
let a = x + dx[i]
let b = y + dy[i]
if (a >= 0 && b >= 0 && a < m && b < n && grid[a][b] == 1) {
res += dfs(a, b)
}
}
return res
}
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (grid[i][j] == 1) {
ans = Math.max(ans, dfs(i, j))
}
}
}
return ans
}
var coinChange = function (coins, amount) {
const dp = new Array(amount + 1).fill(0)
for (let i = 1; i <= amount; i++) {
let min = Number.MAX_SAFE_INTEGER
for (const c of coins) {
if (c <= i) {
min = Math.min(min, dp[i - c] + 1)
}
}
dp[i] = min
}
return dp[amount] === Number.MAX_SAFE_INTEGER ? -1 : dp[amount]
}
var topKFrequent = function (nums, k) {
const map = new Map()
const heap = new MinHeap(k, (a = {}, b = {}) => {
return a.val <= b.val
})
const res = []
nums.map((item) => {
map.set(item, (map.get(item) || 0) + 1)
})
if (map.size <= k) {
return [...map.keys()]
}
map.forEach((val, key) => {
heap.add({ key, val })
})
while (heap.peek()) {
res.push(heap.pop().key)
}
return res.reverse()
}
var multiply = function (num1, num2) {
if (num1 == '0' || num2 == '0') return '0'
let res = '0'
for (let i = num2.length - 1; i >= 0; i--) {
let carry = 0
let temp = new Array(num2.length - 1 - i).fill(0)
let n2 = num2[i] - '0'
for (let j = num1.length - 1; j >= 0 || carry != 0; j--) {
let n1 = j < 0 ? 0 : num1[j] - 0
let result = n1 * n2 + carry
let product = result % 10
temp.push(product)
carry = Math.floor(result / 10)
}
res = addStrings(res, temp.reverse().join(''))
}
return res
}
let addStrings = (num1, num2) => {
let carry = 0
let res = []
for (
let i = num1.length - 1, j = num2.length - 1;
i >= 0 || j >= 0 || carry != 0;
i--, j--
) {
let x = i < 0 ? 0 : num1[i] - 0
let y = j < 0 ? 0 : num2[j] - 0
let sum = x + y + carry
res.push(sum % 10)
carry = Math.floor(sum / 10)
}
return res.reverse().join('')
}
var largestRectangleArea = function (heights) {
heights.push(-1)
const n = heights.length
const stack = []
let max = 0
for (let i = 0; i < n; i++) {
while (stack.length && heights[stack[stack.length - 1]] > heights[i]) {
const cur = stack.pop()
const j = !stack.length ? 0 : stack[stack.length - 1] + 1
max = Math.max(max, heights[cur] * (i - j))
}
stack.push(i)
}
return max
}
var canCompleteCircuit = function (gas, cost) {
let n = gas.length
for (let i = 0, j; i < n; i = i + j + 1) {
let res = 0
for (j = 0; j < n; j++) {
let k = (i + j) % n
res += gas[k] - cost[k]
if (res < 0) break
}
if (j >= n) return i
}
return -1
}
var isValidBST = function (root) {
return isValid(root, -Infinity, Infinity)
}
var isValid = (root, lower, upper) => {
if (!root) return true
if (root.val <= lower || root.val >= upper) {
return false
}
return (
isValid(root.left, lower, root.val) && isValid(root.right, root.val, upper)
)
}
var maximalRectangle = function (matrix) {
const m = matrix.length
const n = matrix[0].length
const left = new Array(m).fill(0).map(() => new Array(n).fill(0))
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (matrix[i][j] === '1') {
left[i][j] = (j === 0 ? 0 : left[i][j - 1]) + 1
}
}
}
let res = 0
for (let j = 0; j < n; j++) {
const up = new Array(m).fill(0)
const down = new Array(m).fill(0)
let stack = []
for (let i = 0; i < m; i++) {
while (stack.length && left[stack[stack.length - 1]][j] >= left[i][j]) {
stack.pop()
}
up[i] = stack.length === 0 ? -1 : stack[stack.length - 1]
stack.push(i)
}
stack = []
for (let i = m - 1; i >= 0; i--) {
while (stack.length && left[stack[stack.length - 1]][j] >= left[i][j]) {
stack.pop()
}
down[i] = stack.length === 0 ? m : stack[stack.length - 1]
stack.push(i)
}
for (let i = 0; i < m; i++) {
const height = down[i] - up[i] - 1
const area = height * left[i][j]
res = Math.max(area, res)
}
}
return res
}
var searchMatrix = function (matrix, target) {
let m = matrix.length
let n = matrix[0].length
let row = m - 1
let col = 0
while (row >= 0 && col < n) {
if (matrix[row][col] == target) return true
else if (matrix[row][col] > target) {
row--
} else if (matrix[row][col] < target) {
col++
}
}
return false
}
var removeNthFromEnd = function (head, n) {
const dummy = new ListNode(null, head)
let p = dummy
let q = dummy
while (n--) {
p = p.next
}
while (p.next) {
p = p.next
q = q.next
}
q.next = q.next.next
return dummy.next
}
var pathSum = function (root, targetSum) {
const result = []
const dfs = (root, res, sum) => {
if (!root) return
sum -= root.val
res.push(root.val)
if (sum === 0 && !root.left && !root.right) return result.push(res.slice())
dfs(root.left, res.slice(), sum)
dfs(root.right, res.slice(), sum)
}
dfs(root, [], targetSum)
return result
}
var canJump = function (nums) {
let k = 0
const n = nums.length
for (let i = 0; i < n; i++) {
if (i <= k) {
k = Math.max(k, i + nums[i])
if (k >= n - 1) {
return true
}
}
}
return false
}
var longestIncreasingPath = function (matrix) {
const dir = [
[-1, 0],
[1, 0],
[0, -1],
[0, 1],
]
const m = matrix.length
const n = matrix[0].length
const memo = new Array(m).fill(0).map(() => new Array(n).fill(0))
let ans = 0
const dfs = (x, y) => {
if (memo[x][y] !== 0) return memo[x][y]
++memo[x][y]
for (let [a, b] of dir) {
a += x
b += y
if (a >= 0 && b >= 0 && a < m && b < n && matrix[a][b] > matrix[x][y]) {
memo[x][y] = Math.max(memo[x][y], dfs(a, b) + 1)
}
}
return memo[x][y]
}
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
ans = Math.max(ans, dfs(i, j))
}
}
return ans
}
var serialize = function (root) {
if (!root) return '[]'
let q = [root]
let res = []
while (q.length) {
let node = q.shift()
if (!node) res.push('#')
else {
res.push(node.val + '')
q.push(node.left)
q.push(node.right)
}
}
return '[' + res.join(',') + ']'
}
var deserialize = function (data) {
if (data == '[]') return null
let values = data.substring(1, data.length - 1).split(',')
let i = 0
let root = new TreeNode(values[i++])
let q = [root]
while (q.length) {
let node = q.shift()
if (node) {
let left = values[i++]
let right = values[i++]
node.left = left == '#' ? null : new TreeNode(left)
node.right = right == '#' ? null : new TreeNode(right)
q.push(node.left)
q.push(node.right)
}
}
return root
}
var deleteDuplicates = function (head) {
const dummy = new ListNode(null, head)
let p = dummy
while (p.next) {
let q = p.next
while (q && q.val == p.next.val) {
q = q.next
}
if (q === p.next.next) p = p.next
else p.next = q
}
return dummy.next
}
var search = function(nums, target) {
let l = 0
let r = nums.length - 1
while(l < r){
let m = l + ((r - l) >> 1)
if(nums[m] >= target) r = m
else l = m + 1
}
return nums[l] === target ? l : -1
};
var search = function(nums, target) {
let l = 0
let r = nums.length - 1
while(l < r){
let m = l + ((r - l + 1) >> 1)
if(nums[m] <= target) l = m
else r = m - 1
}
return nums[l] === target ? l : -1
};
var permutation = function (s) {
s = Array.from(s).sort()
const res = []
const n = s.length
const vis = {}
const dfs = (str) => {
if (str.length === n) return res.push(str)
for (let i = 0; i < n; i++) {
if (i >= 1 && s[i] === s[i - 1] && !vis[i - 1]) continue
if (vis[i]) continue
vis[i] = true
dfs(str + s[i])
vis[i] = false
}
}
dfs('')
return res
}