每日一题:翻转链表

97 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

lettcode206翻转链表

一、题目描述:

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例:

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

二、思路分析:

  1. 迭代法:我们可以直接使用链表循环,设定两个指针prev和cur指向上个节点和当前节点,然后让cur的下个节点为prev,一直循环到结束即可将链表翻转。
  2. 递归法:除了直接循环外,我们可以定义一个当前两个节点翻转的方法,当前节点存在的话就将当前节点和下个节点传入自身,递归调用翻转函数,知道当前节点为空,即遍历处理结束。

具体实现看下面的代码

三、AC 代码:

  1. 迭代法
/**
 * 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) {
    // 定义两个指针prev和cur指向相邻两个节点,使本来的prev.next->cur的指向改为cur.next->prev(反指过来),断开prev.next指向。循环到最后,cur为null,prev为最后一个节点,return prev即为新链表的头节点
    let prev=null, cur = head;
    while (cur) {
        // 解构赋值方法
        [cur.next, prev, cur] = [prev, cur, cur.next]
        // let next = cur.next  // 保存下个节点next
        // cur.next = prev      // 翻转:当前节点的下一个指向前一个节点
        // prev = cur           // prev和cur指针同时后移,进行下一次循环
        // cur = next
    }
    return prev;    // cur为空时结束循环,cur为null,prev为队尾节点,即新的链表的头节点
};
  1. 递归法
var reverseList = function(head) {
    // 给一个两个节点的翻转方法
    return reverse(null, head)
};
var reverse = function(pre, cur) {
    if (cur) {
        // 翻转当前两个节点
        let next = cur.next
        cur.next = pre; // 当前节点指向上个节点
        return reverse(cur, next)  //继续翻转当前节点和下个节点
    }
    return pre;  // cur为空结束循环
}