本文首发于 语雀文档
题目
流程图、调试代码
第 1 次尝试
完全写不出来,没有思路。
但也不难,无非就是调换顺序,存储好上一个节点,修改当前节点的 next 为上一节点,但就纠结的一点是,第一个节点,它的上一个节点是多少?
但没有想到,第一个节点它根本不需要跳过,第一个节点最后它肯定是变成最后一个节点,那势必它的 next 肯定就是 null 啦。
这就一下好理解了。
第 2 次尝试(通过测试用例)
流程图
代码
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
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
};
复制代码
总结
要记得先暂存 curr 当前节点的 next 下一个,不然链表关系就断了。
第 3 次尝试
题目说除了迭代,还可以使用递归。
为了进一步弄清楚,迭代和递归的区别于转换,我觉得继续尝试一下。好吧,试了下,写不出来,总觉的差在哪了
总结
看了题解发现,主要把握三点:
- 如何 return
因为我们需要 return 的头节点是最后的节点,那只有一种办法,那就是一层层 return 递归函数中 return 中的值,这样才能把最底层嵌套里的最后节点拿出来
- 如何修改指向
通过以上一点,我们可以知道,递归函数的 return,是需要一直 return 到最外层的,所以期间不得对其做修改的。
平时我们一般用到 xxx.next 就完了,但这里就需要用到 next.next,这也是我没想到的
第 4 次尝试(通过测试用例)
代码
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function (head) {
if (head === null || head.next === null) {
return head
}
const result = reverseList(head.next)
head.next.next = head
head.next = null
return result
};
复制代码
总结
什么是递归,就是最里面的先执行。
先举例从里层算,一层层往后推,找到重复部分,然后封起来,考虑边界情况(比如:输入的 head 就是 null)。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END