问:
- 剑指 Offer 61. 扑克牌中的顺子
- 剑指 Offer 63. 股票的最大利润
- 剑指 Offer 64. 求1+2+…+n
- 剑指 Offer 65. 不用加减乘除做加法
- 剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
- 剑指 Offer 66. 构建乘积数组 解:
- 用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
};
- 创建并维持一个单调递增的栈,遍历价格数组,当前值如果比栈内最后一个数据小,就弹出并结算一次购入的结果。
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])
};
- 递归,用逻辑与代替if判断
const sumNums = function(n) {
return n && (n += sumNums(n - 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
};
- 遍历二叉树,为空或者为要找的节点时都直接返回。那么对于后序遍历来说,当前节点会接收到左右子树传来的是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)
};
- 对于每个位置来说,它的值就是左边总乘积 * 右边总乘积。所以生成一个辅助数组,记录每个数左边总乘积是多少。然后倒序遍历原数组,设置一个变量记录右边总乘积,跟辅助数组对应位置相乘就可以得到结果数组
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
};