算法学习记录(六十七)

94 阅读1分钟

问:

  1. 剑指 Offer 61. 扑克牌中的顺子
  2. 剑指 Offer 63. 股票的最大利润
  3. 剑指 Offer 64. 求1+2+…+n
  4. 剑指 Offer 65. 不用加减乘除做加法
  5. 剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
  6. 剑指 Offer 66. 构建乘积数组 解:
  7. 用set记录出现的数字,出现重复的就返回false,若无重复,则保证最大和最小的差值小于5即可
const isStraight = function(nums) {
    const hashSet = new Set()
    let min = 14
    let max = -1
    for (let item of nums) {
        if (hashSet.has(item)) return false
        if (item !== 0) {
            hashSet.add(item)
            min = Math.min(min, item)
            max = Math.max(max, item)
        }
    }
    return max - min < 5
};
  1. 创建并维持一个单调递增的栈,遍历价格数组,当前值如果比栈内最后一个数据小,就弹出并结算一次购入的结果。
const maxProfit = function(prices) {
    if (!prices.length) return 0
    const stack = []
    let max = 0
    prices.forEach(item => {
        while (stack.length && stack[stack.length - 1] > item) {
            const curMin = stack[0]
            const curMax = stack.pop()
            max = Math.max(curMax - curMin, max)
        }
        stack.push(item)
    })
    return Math.max(max, stack[stack.length - 1] - stack[0])
};
  1. 递归,用逻辑与代替if判断
const sumNums = function(n) {
    return n && (n += sumNums(n - 1))
};
  1. a & b左移一位就是a+b的进位信息。a ^ b是a,b的不进位相加。给a,b重新赋值后,若此时的a,b不产生进位信息,那么a ^ b就是要的答案。
const add = function(a, b) {
    while ((a & b) !== 0) {
        const temp = a
        // 不进位相加的结果
        a = a ^ b 
        // 进位信息
        b = (temp & b) << 1
    }
    return a ^ b
};
  1. 遍历二叉树,为空或者为要找的节点时都直接返回。那么对于后序遍历来说,当前节点会接收到左右子树传来的是null | p | q。如果左右子树都不是null,那么当前节点就是答案。否则就是左右子树中不是null的那一个是答案(这意味着另一个节点没有被遍历到,因为另一个节点是被返回节点的子节点)
const lowestCommonAncestor = function(root, p, q) {
    function getRes(node) {
        if (node === q || node === p || !node) return node
        const left = getRes(node.left)
        const right = getRes(node.right)
        if (left && right) return node 
        if (left || right) return left ?? right
    }
    return getRes(root)
};
  1. 对于每个位置来说,它的值就是左边总乘积 * 右边总乘积。所以生成一个辅助数组,记录每个数左边总乘积是多少。然后倒序遍历原数组,设置一个变量记录右边总乘积,跟辅助数组对应位置相乘就可以得到结果数组
const constructArr = function(a) {
    let pre = 1
    const leftArr = []
    const resArr = []
    for (let i = 0; i < a.length; i++) {
        pre *= (a[i - 1] ?? 1)
        leftArr[i] = pre
    }
    pre = 1
    for (let i = a.length - 1; i >= 0; i--) {
        pre *= (a[i + 1] ?? 1)
        resArr[i] = leftArr[i] * pre
    }
    return resArr
};