varstrToInt=function(str){//首先判断开头是不是空白字符if(str.match(/[^\s]|[^\d]/)){const[INT_MIN,INT_MAX]=[Math.pow(-2,31),Math.pow(2,31)-1]const s = str.trim();const res = s.match(/^[\+\-]?\d+/g);if(res >INT_MAX)returnINT_MAX;if(res <INT_MIN)returnINT_MIN;return res;}else{return0;}};
let slow = head
let fast = slow
while(k--){
fast = fast.next
}if(!fast)return slow
if(!fast.next)return slow.next
while(fast?.next){
fast = fast.next
slow = slow.next
}return slow.next
varMinStack=function(){this.stack =[]};/**
* @param {number} x
* @return {void}
*/MinStack.prototype.push=function(x){this.stack.push(x)};/**
* @return {void}
*/MinStack.prototype.pop=function(){this.stack.pop()};/**
* @return {number}
*/MinStack.prototype.top=function(){returnthis.stack[this.stack.length-1]};/**
* @return {number}
*/MinStack.prototype.min=function(){let min =Infinitythis.stack.forEach((num)=>{if(num<min){
min = num
}})return min
};
17 滑动窗口的最大值
constmaxSlidingWindow=(nums,k)=>{const queue =[]const res =[]let len = nums.length
for(let i =0; i < len; i++){while(queue.length && nums[queue.at(-1)]<= nums[i]){
queue.pop()}
queue.push(i)if(queue.length && queue[0]= i-k) queue.shift()if(i>= k-1){
res.push(nums[queue[0]])}}}
18 队列的最大值
varMaxQueue=function(){this.stack =[]this.max =-Infinity};/**
* @return {number}
*/MaxQueue.prototype.max_value=function(){if(this.stack.length)returnthis.max
return-1};/**
* @param {number} value
* @return {void}
*/MaxQueue.prototype.push_back=function(value){this.stack.push(value)if(value >this.max)this.max = value
};/**
* @return {number}
*/MaxQueue.prototype.pop_front=function(){if(this.stack.length){const res =this.stack.shift()if(res ===this.max){this.max = Math.max(...this.stack)}return res
}return-1};
19 顺时针打印矩阵
varspiralOrder=function(matrix){if(!matrix.length)return[]let row = matrix.length
let col = matrix[0].length
const res =[]
size = row*col
let t =0, r = col-1, b = row-1, l =0while(res.length!==size){//从左往右for(let i = l;i<=r;i++) res.push(matrix[t][i])
t++//从左到右可能便利完的矩阵//[[1,2,3],[4,5,6],[7,8,9]]//从上往下for(let i = t; i<=b;i++) res.push(matrix[i][r])
r--//从上到下可能遍历完的矩阵//[[7],[8],[9]]//到这里可能就遍历完了if(res.length===size)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
};
20 栈的压入、弹出序列
varvalidateStackSequences=function(pushed, popped){let stack =[]let i =0//模拟入栈出栈for(item of pushed){
stack.push(item)while(stack.length && stack.at(-1)== popped[i]){
stack.pop()
i++}}return!stack.length
};
21 数组中的重复数字
varfindRepeatNumber=function(nums){let map =newMap()let res
for(num of nums){if(map.get(num)){
res = num
break}
map.set(num,1)}return res
};
22 在排序数组中查找数字I
//法一varsearch=function(nums, target){let res =0for(num of nums){if(num===target)res++}return res
};//法二varsearch=function(nums, target){return nums.filter(item=> item === target).length
};
23 0~n-1中缺失的数字
//等差数列前n项和varmissingNumber=function(nums){const n = nums.length+1let total = Math.floor(n*(n-1)/2)let res = nums.reduce((prev,curr)=> prev+curr,0)return total - res
};
24 二维数组中的查找
//从左下角开始查找 上面的数比它小,右边的数比他大varfindNumberIn2DArray=function(matrix, target){if(!matrix.length)returnfalselet x = matrix.length-1let y =0while(x>=0&& y<matrix[0].length){if(matrix[x][y]=== target){returntrue}elseif(matrix[x][y]>target){
x--}else{
y++}}returnfalse};
25 旋转数组的最小数字
varminArray=function(numbers){let left =0let right = numbers.length-1while(left<right){let mid = left + Math.floor((right-left)/2)//如果中值大于最右边的值,说明最小值在右边if(numbers[mid]> numbers[right]){
left = mid +1}elseif(numbers[mid]<numbers[right]){//如果中值小于最右边的值,说明最小值在左边
right = mid
}else{
right--}}return numbers[left]};
26 第一个只出现一次的字符
varfirstUniqChar=function(s){if(!s)return' 'let map =newMap()for(let str of s){if(map.get(str)){
map.set(str,map.get(str)+1)}else{
map.set(str,1)}}for(let item of map.keys()){if(map.get(item)===1){return item
}}return' '};
27 从上到下打印二叉树
varlevelOrder=function(root, res =[]){if(!root)return[]const queue =[root]while(queue.length){const head = queue.shift()
res.push(head.val)
head.left && queue.push(head.left)
head.right && queue.push(head.right)}return res
};
28 从上到下打印二叉树
varlevelOrder=function(root){if(!root)return[]let res =[]let queue =[root]while(queue.length){const arr =[]let len = queue.length
for(let i=0;i<len;i++){const node = queue.shift()
node.left && queue.push(node.left)
node.right && queue.push(node.right)
arr.push(node.val)}
res.push(arr)}return res
};
29 从上到下打印二叉树
varlevelOrder=function(root){if(!root)return[]const res =[]let queue =[root]let k=0while(queue.length){const arr =[]let len = queue.length
for(let i=0;i<len;i++){
node = queue.shift()
node.left && queue.push(node.left)
node.right && queue.push(node.right)
arr.push(node.val)}if(k%2===1) arr.reverse()
res.push(arr)
k++}return res
};
varmirrorTree=function(root){if(!root)returnnullconst left =mirrorTree(root.left)const right =mirrorTree(root.right)
root.left = right
root.right = left
return root
};
constsum=(num)=>{let a =0while(num){
a+=num%10
num=parseInt(num/10)}return a
}varmovingCount=function(m, n, k){const res =Array(m).fill(0).map(()=>Array(n).fill(false))constcheck=(i,j)=>{if(i<0|| i>m-1|| j<0|| j>n-1)return0if(res[i][j])return0if(sum(i)+sum(j)>k)return0if(sum(i)+sum(j)<=k) res[i][j]=true//从该点继续寻找return1+check(i-1,j)+check(i+1,j)+check(i,j-1)+check(i,j+1)}returncheck(0,0)};
35 二叉树中和为某一值的路径
varpathSum=function(root, target){const res =[]//深度优先遍历constdfs=(root, count =0, nums =[])=>{if(root){
count+=root.val
nums =[...nums,root.val]//路径和相等并且最后一个节点是叶子节点if(count===target &&!root.left &&!root.right){
res.push(nums)}dfs(root.left, count, nums)dfs(root.right, count, nums)}}dfs(root)return res
};
36 二叉搜索树和双向链表
vartreeToDoublyList=function(root){if(!root)returnlet pre, head =null//中序遍历从小到大排序constdfs=(root)=>{if(!root)returndfs(root.left)//当pre为null时为最左边的节点
pre!=null? pre.right = root : head = root
root.left = pre
pre = root
dfs(root.right)}dfs(root)//现在pre为尾节点,head为头节点
head.left = pre
pre.right = head
return head
};
37 二叉搜索数的第k大节点
//后续遍历varkthLargest=function(root, k){const res =[]constdfs=(root)=>{if(!root)returnnulldfs(root.right)
res.push(root.val)dfs(root.left)}dfs(root)return res[k-1]};
38 二叉树的深度
varmaxDepth=function(root){let max =0if(!root)return0//深度优先遍历constdfs=(root, depth =1)=>{if(!root){if(max<depth-1) max = depth -1return}dfs(root.left, depth+1)dfs(root.right, depth+1)}dfs(root)return max
};
39 平衡二叉树
varisBalanced=function(root){if(!root)returntrue//寻找左子树和右子树的最大深度constdfs=(root)=>{if(!root)return0return Math.max(dfs(root.left),dfs(root.right))+1}let left =dfs(root.left)let right =dfs(root.right)if(Math.abs(left-right)>1)returnfalsereturnisBalanced(root.left)&&isBalanced(root.right)};