问:
-
N个加油站组成一个环形,给定两个长度都是N的非负数组oil和dis。oil[i]代表第i个加油站存多少单位个油,dis[i]代表第i个加油站到下个加油站需要多少单位个油。假设有一辆车初始油为空,从某个加油站出发,最终能回到这个加油站,那么这个加油站称为良好出发点,否则不是。请返回每个加油站是否为良好出发点。
-
一颗所有节点的值都不一样的二叉树原本是搜索二叉树,但是有两个节点调换了位置,使得这个二叉树不再是搜索二叉树,找到这两个错误节点并返回。
解: 1.
function checkStartPoint(oil, dis) {
// 是否存在非负数
let nonnegative = -1
const res = []
// 将oil和dis对应位置相减。
// 此时oil表明需要多少油或者富裕多少油
oil.forEach((item, idx) => {
res.push(false)
oil[idx] = item - dis[idx]
if (oil[idx] >= 0 && nonnegative === -1) nonnegative = idx
})
// 都是负数,则没有良好出发点
if (nonnegative === -1) return res
// 存在一个正数出发点,那就从这个点开始
let rest = 0
let need = 0
// 开始的加油站
let start = nonnegative
// 要去的加油站
let end = nonnegative === oil.length - 1 ? 0 : nonnegative + 1
// 初始油
rest = oil[start]
while (start !== end) {
// 看能否走到下一个加油站
if (rest + oil[end] >= 0) {
// 能走过,把油结算一次
rest += oil[end]
end = end === oil.length - 1 ? 0 : end + 1
} else {
// 走不过,看看能否从开始加油站之前的加油站开始
// [-2, 1, -3, 5, -1, -2, 2, 5, -4]
while (start !== end) {
// 如果start来到了数组第0个,那上一个加油站就是数组最后一个
const pre = start === 0 ? oil[oil.length - 1] : oil[start - 1]
// 如果上一个加油站是能到开始加油站的
if (pre >= need) {
rest += pre
need = 0
start = start === 0 ? oil.length : start - 1
// 如果这个开始加油站可以带着足够多的rest冲过end,那么跳出循环
if (rest + oil[end] >= 0) {
break
}
} else {
// 上一个加油站是负数,代表需要更多油才能过来,继续去找再上一个加油站
need += -pre
rest += pre
start = start === 0 ? oil.length - 1 : start - 1
}
}
// 没找到能让车冲过end的开始加油站,直接结束
if (rest + oil[end] < 0) return res
// 否则就是找到了
}
}
// 由start开始的加油站连同了
if (start === end) {
res[start] = true
}
// 已经知道了一个可以连通全局的加油站,那么只要在遍历一次,那些可以连通到该加油站的加油站都可以连同全局
end = start === 0 ? oil.length - 1 : start - 1
need = 0
while (start !== end) {
if (oil[end] >= need) {
res[end] = true
} else {
need += -oil[end]
}
end = end === 0 ? oil.length - 1 : end - 1
}
return res
}
- 中序遍历,出现降序的时候有两种情况。一个是互换的节点是相邻节点,一个是不是相邻节点。
function findErrorNodes(head) {
let firstFlag = false
let preNode = null
const res = [null, null]
function getRes(node) {
if (!node) return
getRes(node.left)
if (preNode) {
if (node.value < preNode.value) {
// 第一次降序的第一个节点
if (!firstFlag) {
res[0] = preNode
firstFlag = true
} else {
// 第二次降序的第二个节点
res[1] = node
}
}
}
preNode = node
getRes(node.right)
}
getRes(head)
return res
}