leetcode剑指offer75题

1 替换空格

在这里插入图片描述

var replaceSpace = function(s) {
    const str = s.split(' ');
    return str.join('%20')
};

2 左旋转字符串

在这里插入图片描述

var reverseLeftWords = function(s, n) {
    const s1 = s.slice(n)
    const s2 = s.slice(0,n)
    return s1+s2
};

3 表示数值的字符串

在这里插入图片描述在这里插入图片描述

//\d+ 匹配整数 1次或多次
//(\.\d*)? 满足小数条件12 ?匹配0次或1次, 0次即整数 1次即小数
// \.\d+ 满足小数条件3

var isNumber = function(s) {
    const str = s.trim();
    const reg = /^[\+\-]?((\d+(\.\d*)?)|(\.\d+))(e[\+\-]?\d+)?$/i;
    return reg.test(str)
};

4 把字符串转换成整数

在这里插入图片描述

var strToInt = 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) return INT_MAX;
        if (res < INT_MIN) return  INT_MIN;
        return res;
    } else {
        return 0;
    }
};

5 从尾到头打印链表

在这里插入图片描述

var reversePrint = function(head) {
    const arr = []
    while(head?.next) {
        arr.push(head.val);
        head = head.next
    }
    if(head?.val || head?.val===0) arr.push(head.val);
    return arr.reverse()
};

6 反转链表

在这里插入图片描述

var reverseList = function(head) {
    let prev = null
    let curr = head
    while(curr) {
        const next  = curr.next
        curr.next = prev
        prev=curr
        curr = next
    }
    return prev
};

7 复杂链表的复制

在这里插入图片描述

var copyRandomList = function(head) {
    if(!head) return null
    const map = new Map()
    let prev = head
    //创建一个新的节点
    while(prev){
        map.set(prev, new Node(prev.val))
        prev = prev.next
    }
    map.set(null,null)
    prev = head
    //将各个链表节点连接起来
    while(prev) {
        map.get(prev).next = map.get(prev.next)
        map.get(prev).random = map.get(prev.random)
        prev = prev.next
    }
    return map.get(head)
};

8 删除链表的节点

在这里插入图片描述

var deleteNode = function(head, val) {
    if(!head) return null
    let newNode = new ListNode(0,head)
    let prev = newNode
    let curr = head
    while(curr){
        if(curr.val === val) {
            prev.next = curr.next
        } else {
            prev = curr
        }
        curr = curr.next
    }
    return newNode.next
};

9 链表中倒数第k个节点

在这里插入图片描述

 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

10 合并两个排序的链表

在这里插入图片描述

let prev = new ListNode(null)
    let curr = prev
    while(l1 && l2){
        if(l1?.val >= l2?.val){
            prev.next = l2
            l2 = l2?.next
            prev = prev.next
        } else {
            prev.next = l1
            l1 = l1?.next
            prev = prev.next
        }
    }
    if (l1) prev.next = l1
    if (l2) prev.next = l2
    return curr.next

11 两个链表的第一个公共节点

在这里插入图片描述

var getIntersectionNode = function(headA, headB) {
    let prevA = headA
    let prevB = headB
    while(prevA !== prevB) {
        prevA = prevA ? prevA.next : headB
        prevB = prevB ? prevB.next : headA
    }
    return prevA
};

12 调整数组顺序使奇数位于偶数前面

在这里插入图片描述

var exchange = function(nums) {
    const arr = []
    nums.forEach((num)=>{
        if(num%2 === 1) {
            arr.unshift(num)
        } else {
            arr.push(num)
        }
    })
    return arr
};

13 和为s的两个数字

在这里插入图片描述

var twoSum = function(nums, target) {
    let l = 0 
    let r = nums.length-1
    while(l!==r){
        const res = nums[l]+nums[r]
        if(res > target){
            r--
        } else if (res < target) {
            l++
        } else {
            return [nums[l],nums[r]]
        }
    }
};

14 翻转单词顺序

在这里插入图片描述

var reverseWords = function(s) {
    const arr = s.trim().split(' ').filter(item=>item)
    return arr.reverse().join(' ')
};

15 用两个栈实现队列

在这里插入图片描述

var CQueue = function() {
    this.stackA = []
    this.stackB = []
};

/** 
 * @param {number} value
 * @return {void}
 */
CQueue.prototype.appendTail = function(value) {
    this.stackA.push(value)
};

/**
 * @return {number}
 */
CQueue.prototype.deleteHead = function() {
    if(this.stackB.length){
        return this.stackB.pop()
    } else {
        while(this.stackA.length) {
            this.stackB.push(this.stackA.pop())
        }
        if(!this.stackB.length){
            return -1
        } else {
            return this.stackB.pop()
        }
    }
};

16 包含min函数的栈

在这里插入图片描述

var MinStack = 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() {
    return this.stack[this.stack.length-1]
};

/**
 * @return {number}
 */
MinStack.prototype.min = function() {
    let min = Infinity
    this.stack.forEach((num)=>{
        if(num<min){
            min = num
        }
    })
    return min
};

17 滑动窗口的最大值

在这里插入图片描述

const maxSlidingWindow = (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 队列的最大值

在这里插入图片描述

var MaxQueue = function() {
    this.stack = []
    this.max = -Infinity
};

/**
 * @return {number}
 */
MaxQueue.prototype.max_value = function() {
    if(this.stack.length) return this.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 顺时针打印矩阵

在这里插入图片描述

var spiralOrder = 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 =0
    while(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 栈的压入、弹出序列

在这里插入图片描述

var validateStackSequences = 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 数组中的重复数字

在这里插入图片描述

var findRepeatNumber = function(nums) {
    let map = new Map()
    let res
    for(num of nums){
        if (map.get(num)){
            res = num
            break
        } 
        map.set(num,1)
    }
    return res
};

22 在排序数组中查找数字I

在这里插入图片描述

//法一
var search = function(nums, target) {
    let res = 0
    for(num of nums){
        if(num===target)res++
    }
    return res
};

//法二
var search = function(nums, target) {
    return nums.filter(item => item === target).length
};

23 0~n-1中缺失的数字

在这里插入图片描述

//等差数列前n项和
var missingNumber = function(nums) {
    const n = nums.length+1
    let total = Math.floor(n*(n-1)/2)
    let res = nums.reduce((prev,curr) => prev+curr, 0)
    return total - res
};

24 二维数组中的查找

在这里插入图片描述

//从左下角开始查找 上面的数比它小,右边的数比他大
var findNumberIn2DArray = function(matrix, target) {
    if(!matrix.length) return false
    let x = matrix.length-1
    let y = 0
    while(x>=0 && y<matrix[0].length){
        if(matrix[x][y]=== target){
            return true
        } else if (matrix[x][y]>target){
            x--
        } else {
            y++
        }
    }
    return false
};

25 旋转数组的最小数字在这里插入图片描述

var minArray = function(numbers) {
    let left = 0
    let right = numbers.length-1
    while(left<right){
        let mid = left + Math.floor((right-left) / 2)
        //如果中值大于最右边的值,说明最小值在右边
        if (numbers[mid] > numbers[right]){
            left = mid + 1
        } else if (numbers[mid] <numbers[right]){
            //如果中值小于最右边的值,说明最小值在左边
            right = mid
        } else {
            right--
        }
    }
    return numbers[left]
};

26 第一个只出现一次的字符

在这里插入图片描述

var firstUniqChar = function(s) {
    if(!s) return ' '
    let map = new Map()
    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 从上到下打印二叉树

在这里插入图片描述

var levelOrder = 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 从上到下打印二叉树

在这里插入图片描述

var levelOrder = 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 从上到下打印二叉树

在这里插入图片描述

var levelOrder = function(root) {
    if(!root) return []
    const res = []
    let queue = [root]
    let k=0
    while(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
};

30 树的子结构

在这里插入图片描述

var isSubStructure = function(A, B) {
    //空树不是任意一个树的子结构
    if(!A || !B) return false

    const dfs = (A,B) => {
        //如果找到B为null都没有返回false
        if(!B) return true
        //如果A都为空了就不需要查找直接返回false
        if(!A || A.val !== B.val) return false
        //如果值相等,则比较剩余左右子树
        return dfs(A.left,B.left) && dfs(A.right,B.right)
    }
    return dfs(A,B) || isSubStructure(A.left,B) || isSubStructure(A.right,B)
};

31 二叉树的镜像

在这里插入图片描述

var mirrorTree = function(root) {
    if(!root) return null
    const left = mirrorTree(root.left)
    const right = mirrorTree(root.right)
    root.left = right
    root.right = left
    return root
};

32 对称的二叉树

在这里插入图片描述

var isSymmetric = function(root) {
    return check(root,root)
};

const check = (left,right) => {
    if(!left && !right) return true
    if(!left || !right) return false
    return left.val === right.val && check(left.left,right.right) && check(left.right,right.left)
}

33 矩阵中的路径

在这里插入图片描述

var exist = function(board, word) {
    const xlim = board.length
    const ylim = board[0].length
    const k = 0
    const check = (i,j,k) => {
        //判断是否超出边界
        if(i<0|| i>xlim-1 || j<0 || j>ylim-1) return false 
        //是否已经走过
        if(!board[i][j]) return false
        //当前位置并不是下一个字母所在位置
        if(board[i][j] !== word[k]) return false

        //如果已经遍历完所有字母
        if(k===word.length-1) return true
        const init = board[i][j]
        //标记已经走过的点
        board[i][j] = false
        k++
        //继续寻找
        const res = check(i-1,j,k) || check(i+1,j,k) || check(i,j-1,k) || check(i,j+1,k)
        //恢复初始值,清除标记
        board[i][j] = init
        return res
    }
    for(let i=0;i<xlim;i++) {
        for(let j = 0;j<ylim;j++){
            if(board[i][j]===word[k] && check(i,j,k))
            {
                return true
            }
        }
    }
    return false
};

34 机器人的运动范围

在这里插入图片描述

const sum = (num) => {
    let a = 0
    while(num) {
        a+=num%10
        num=parseInt(num/10)
    }
    return a
}

var movingCount = function(m, n, k) {
    const res = Array(m).fill(0).map(() => Array(n).fill(false))
    const check = (i,j)=>{
        if(i<0 || i>m-1 || j<0 || j>n-1) return 0
        if(res[i][j]) return 0
        if(sum(i)+sum(j)>k) return 0
        if(sum(i)+sum(j)<=k) res[i][j] = true
        //从该点继续寻找
        return 1+check(i-1,j)+check(i+1,j)+check(i,j-1)+check(i,j+1)
    }

    return  check(0,0)
};

35 二叉树中和为某一值的路径

在这里插入图片描述

var pathSum = function(root, target) {
    const res = []
    //深度优先遍历
    const dfs = (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 二叉搜索树和双向链表

在这里插入图片描述

var treeToDoublyList = function(root) {
    if(!root) return 
    let pre, head = null
    //中序遍历从小到大排序
    const dfs = (root) => {
        if(!root) return 
        dfs(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大节点

在这里插入图片描述

//后续遍历
var kthLargest = function(root, k) {
    const res = []
    const dfs = (root) => {
        if(!root) return null
        dfs(root.right) 
        res.push(root.val)
        dfs(root.left)
    }
    dfs(root)
    return res[k-1]
};

38 二叉树的深度

在这里插入图片描述

var maxDepth = function(root) {
    let max = 0
    if(!root) return 0
    //深度优先遍历
    const dfs = (root, depth = 1) => {
        if(!root) {
            if(max<depth-1) max = depth - 1
            return 
        }
        dfs(root.left, depth+1)
        dfs(root.right, depth+1)
    }
    dfs(root)
    return max
};

39 平衡二叉树

var isBalanced = function(root) {
    if(!root) return true
    //寻找左子树和右子树的最大深度
    const dfs = (root) => {
        if (!root) return 0
        return 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) return false
    return isBalanced(root.left) && isBalanced(root.right)
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值