记录2道算法题
删除链表中间节点
单向链表只有 next 指向下一个节点,是没有办法获取到前一个节点的,看到这道题的时候还以为是什么脑筋急转弯题目,事实上根本不可能把节点删除的,需要知道被删除节点的前一个节点,然后改变 next 指向,才能把这个节点从链表中删除。
正在苦恼的时候突然想到了之前看到的题目,题目后面有个注解 不能修改节点的 val 值。当时还不知道为什么要有这个限制。然后突然想到,这道题好像没有这个限制。那是不是只需要把 next 节点的值赋值给当前的节点,然后一直重复操作。然后把最后的节点给删掉。这样看着就像是把节点给删掉了。
那就来试试看测试过不过吧。
function deleteNode(node) {
// 为了删除最后的节点,所以要停在最一个节点的前一个节点
while (node.next.next) {
node.val = node.next.val
node = node.next
}
// 倒数第二个节点赋值最后一个节点val
// 删除最后一个节点
node.val = node.next.val
node.next = null
}
测试通过!
两数相加ii
像加法一样,每一位一个节点。大于10会进1位。新生成一个链表
1 -> 2 -> 3 -> 4 3 -> 1 -> 5 结果: 1 -> 5 -> 4 -> 9
遇到的麻烦是链表是反过来的,而且还可能长度不一样。可以用栈来解决。
function addTwoNumbers(l1, l2) {
const stack1 = []
const stack2 = []
// 把节点装入栈中
while (l1) {
stack1.push(l1)
l1 = l1.next
}
while (l2) {
stack2.push(l2)
l2 = l2.next
}
// 用最长的作为要相加的位数
let len = Math.max(stack1.length, stack2.length)
let node
let k = 0
let o = 0
for (let i = 0; i < len; i++) {
// 不够就用0填充
const s1 = stack1.pop()?.val ?? 0
const s2 = stack2.pop()?.val ?? 0
let sum = s1 + s2 + k
// 这里用了两个变量,o是代表当前加了之后是否进 1 位
// k 是代表上一次计算是否有进 1 位
// k 进一位的话,当前位要 +1
if (sum >= 10) {
o = sum >= 10 ? 1 : 0
sum -= 10
} else {
o = 0
}
if (!node) {
// 第一次没有节点
node = new ListNode(sum)
} else {
// 前面已经算了几位了
// 这里的细节是将链表倒着添加
// 4
// 3 -> 4
// 这样的感觉,这样最后就可以直接输出 node
node = new ListNode(sum, node)
}
// 更新 k 为 这一位的 是否进 1 位
k = o
}
// 还要再多算一轮,就是最后一次计算时 需要进 1 位的情况
// 例如 5 + 5 = 10
if (k === 1) {
node = new ListNode(1, node)
}
return node
}
结束