三指针交替前进法反转单链表 & 递归法反转单链表

题目

给你单链表的头节点head ,请你反转链表,并返回反转后的链表。如下图所示:
在这里插入图片描述
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

解决思路

在这里插入图片描述

  • 思路1:3指针交替前进法进行反转
    • 初始化3个指针:定义指针pre指向null,定义指针cur指向头节点,定义指针next指向cur的下一个节点。
    • 3个指针的作用:
      • pre指向已经反转部分链表的头结点。
      • cur指向未反转部分链表的头节点。
      • next指向cur的下一个节点。
  • 思路2:递归反转法
    • 先递归遍历到链表的最后一个节点。
    • 然后从后向前改变指针的指向。

代码

  • 思路1对应的C++代码:
# include <stdio.h>

struct ListNode {
    int val;
    ListNode *next;
    ListNode(): val(0), next(nullptr) {}
    ListNode(int x): val(x), next(nullptr) {}
    ListNode(int x, ListNode *next): val(x), next(next) {} 
};


class Solution {
public:
    ListNode *reverseList(ListNode *head) {
        if (nullptr == head || nullptr == head->next) {
            return head;
        }

        ListNode *pre = nullptr;
        ListNode *cur = head;
        ListNode *nex = head->next;

        while (cur) {
            cur->next = pre;
            pre = cur;
            (cur = nex) && (nex = nex->next);    // 技巧,用&&的作用:当nex为null时不再执行nex = nex->next
        }

        return pre;
    }
};


int main() {
    // 创建单链表
    ListNode *a = new ListNode(1);
    ListNode *b = new ListNode(2);
    ListNode *c = new ListNode(3);
    ListNode *d = new ListNode(4);
    ListNode *e = new ListNode(5);

    a->next = b;
    b->next = c;
    c->next = d;
    d->next = e;

    ListNode *head = a;
    printf("before reverse: ");
    while (head)
    {
        printf("%d ", head->val);
        head = head->next;
    }
    printf("\n");

    // 反转单链表
    head = a;
    Solution *solution = new Solution();
    ListNode *ret = solution->reverseList(head);

    printf("after reverse: ");
    while (ret)
    {
        printf("%d ", ret->val);
        ret = ret->next;
    }

    return 0;
}
  • 思路2对应的C++代码:
# include <stdio.h>

struct ListNode {
    int val;
    ListNode *next;
    ListNode(): val(0), next(nullptr) {}
    ListNode(int x): val(x), next(nullptr) {}
    ListNode(int x, ListNode *next): val(x), next(next) {} 
};

// 基于递归进行反转,先遍历到原链表的最后一个节点,然后改变指针的方向
class Solution {
public:
    ListNode *reverseList(ListNode *head) {
        if (nullptr == head || nullptr == head->next) {
            return head;
        }

        ListNode *cur = head->next;                 // 指向head的下一个节点
        ListNode *pre = reverseList(cur);           // 先递归到链表的最后一个节点
        head->next = cur->next;
        cur->next = head;       // 改变指针的指向
        cur = cur->next;
        return pre;
    }
};


int main() {
    // 创建单链表
    ListNode *a = new ListNode(1);
    ListNode *b = new ListNode(2);
    ListNode *c = new ListNode(3);
    ListNode *d = new ListNode(4);
    ListNode *e = new ListNode(5);

    a->next = b;
    b->next = c;
    c->next = d;
    d->next = e;

    ListNode *head = a;
    printf("before reverse: ");
    while (head)
    {
        printf("%d ", head->val);
        head = head->next;
    }
    printf("\n");

    // 反转单链表
    head = a;
    Solution *solution = new Solution();
    ListNode *ret = solution->reverseList(head);

    printf("after reverse: ");
    while (ret)
    {
        printf("%d ", ret->val);
        ret = ret->next;
    }

    return 0;
}
  • 思路1对应的python代码
# -*- coding: utf-8 -*-

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next


class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        if not head or not head.next:
            return head

        pre = None
        cur = head
        nex = head.next

        while cur:
            cur.next = pre
            pre = cur
            cur = nex
            if nex:
                nex = nex.next

        return pre


def main():
    a = ListNode(1)
    b = ListNode(2)
    c = ListNode(3)
    d = ListNode(4)
    e = ListNode(5)

    a.next = b
    b.next = c
    c.next = d
    d.next = e
    head = a

    print('before reverse: ', end='')
    while head:
        print(head.val, end=' ')
        head = head.next
    print()

    head = a
    solution = Solution()
    ret = solution.reverseList(head)

    print("after reverse: ", end='')
    while ret:
        print(ret.val, end=' ')
        ret = ret.next


if __name__ == "__main__":
    main()
  • 思路2对应的python代码
# -*- coding: utf-8 -*-

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next


# 基于递归进行反转,先遍历到原链表的最后一个节点,然后改变指针的方向
class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        if not head or not head.next:
            return head

        cur = head.next
        pre = self.reverseList(cur)
        head.next = cur.next
        cur.next = head
        cur = cur.next
        return pre


def main():
    a = ListNode(1)
    b = ListNode(2)
    c = ListNode(3)
    d = ListNode(4)
    e = ListNode(5)

    a.next = b
    b.next = c
    c.next = d
    d.next = e
    head = a

    print('before reverse: ', end='')
    while head:
        print(head.val, end=' ')
        head = head.next
    print()

    head = a
    solution = Solution()
    ret = solution.reverseList(head)

    print("after reverse: ", end='')
    while ret:
        print(ret.val, end=' ')
        ret = ret.next


if __name__ == "__main__":
    main()

说明

  • 对应LeetCode第206题。
  • 链接:https://leetcode-cn.com/problems/reverse-linked-list/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值