算法,从简单刷起~206. 反转链表

本文首发于 语雀文档

题目

leetcode-cn.com/problems/re…

流程图、调试代码

github.com/blueju/leet…/

第 1 次尝试

完全写不出来,没有思路。

但也不难,无非就是调换顺序,存储好上一个节点,修改当前节点的 next 为上一节点,但就纠结的一点是,第一个节点,它的上一个节点是多少?

但没有想到,第一个节点它根本不需要跳过,第一个节点最后它肯定是变成最后一个节点,那势必它的 next 肯定就是 null 啦。

这就一下好理解了。


第 2 次尝试(通过测试用例)

流程图

image.png

代码

/**
 * 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 次尝试

题目说除了迭代,还可以使用递归。
为了进一步弄清楚,迭代和递归的区别于转换,我觉得继续尝试一下。

好吧,试了下,写不出来,总觉的差在哪了

总结

看了题解发现,主要把握三点:

  1. 如何 return

因为我们需要 return 的头节点是最后的节点,那只有一种办法,那就是一层层 return 递归函数中 return 中的值,这样才能把最底层嵌套里的最后节点拿出来

  1. 如何修改指向

通过以上一点,我们可以知道,递归函数的 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)。
image.png

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享