题解 | #反转链表#

反转链表

http://www.nowcoder.com/practice/75e878df47f24fdc9dc3e400ec6058ca

算法思想一:双指针迭代

解题思路:

(1)定义两个指针: pre 和 cur ;pre 在前 cur 在后。
(2)每次让 pre 的 next 指向 cur ,实现一次局部反转
(3)局部反转完成之后, pre 和 cur 同时往前移动一个位置
(4)循环上述过程,直至 pre 到达链表尾部

图解:

代码展示:

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回ListNode
    def ReverseList(self, pHead):
        # write code here
        # 空链表或只有一个节点得链表
        if not pHead&nbs***bsp;not pHead.next:
            return pHead
        cur = pHead
        pre = None
        # 循环移动curent和pre,移动过程中反转 curent.next=pre
        while cur:
            next_node = cur.next
            cur.next = pre
            pre = cur
            cur = next_node
        return pre

复杂度分析:

时间复杂度O(N):N表示链表长度,双指针一次遍历
空间复杂度O(1):常数大小空间指针

算法思想二:递归

解题思路:

递归上来就先写终止条件:如果head为空或者head.next为空,返回head
(1)新头结点 res 指向尾结点,此处进入递归,递归一直到遍历到尾结点时才会返回
(2)每一层递归,该层递归中的 head 会让下一个节点指向自己,head.next.next = head;然后head自己指向空。以此达到反转的目的。
(3)返回新链表的头结点newHead

代码展示:

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode ReverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode res = ReverseList(head.next);
        head.next.next = head;
        head.next = null;
        return res;
    }
}

复杂度分析:
时间复杂度O(N):N表示链表长度
空间复杂度O(N):递归机制的实现需要借助于栈,该程序中递归栈的深度为N-1,所以空间复杂度为线性。

算法思路三:使用额外栈

解题思路:
新建额外的新栈 stack
循环遍历原链表,并将链表元素入栈,遍历结束后,将栈内元素依次出栈并建立链表

图解:

代码展示:

public ListNode ReverseList(ListNode head) {
    Stack<ListNode> stack = new Stack<>();
    //把链表节点全部摘掉放到栈中
    while (head != null) {
        stack.push(head);
        head = head.next;
    }
    if (stack.isEmpty())
        return null;
    ListNode node = stack.pop();
    ListNode dummy = node;
    //栈中的结点全部出栈,然后重新连成一个新的链表
    while (!stack.isEmpty()) {
        ListNode tempNode = stack.pop();
        node.next = tempNode;
        node = node.next;
    }
    //最后一个结点就是反转前的头结点,一定要让他的next
    //等于空,否则会构成环
    node.next = null;
    return dummy;
}
复杂度分析:
时间复杂度O(N):N表示链表长度
空间复杂度O(N):辅助栈空间




全部评论
你图一错了,(1)定义两个指针: pre 和 cur ;pre 在前 cur 在后。 你图里相反
1 回复 分享
发布于 2022-11-30 22:43 北京

相关推荐

07-02 13:52
武汉大学 golang
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
昨天 18:13
点赞 评论 收藏
分享
程序员牛肉:主要是因为小厂的资金本来就很吃紧,所以更喜欢有实习经历的同学。来了就能上手。 而大厂因为钱多,实习生一天三四百的就不算事。所以愿意培养你,在面试的时候也就不在乎你有没有实习(除非是同级别大厂的实习。) 按照你的简历来看,同质化太严重了。项目也很烂大街。 要么换项目,要么考研。 你现在选择工作的话,前景不是很好了。
点赞 评论 收藏
分享
流浪的神仙:无恶意,算法一般好像都得9硕才能干算法太卷啦
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
06-27 14:11
很喜欢小米的新车,校招薪资每月22k,攒多久能买?
测试糕手手:别看工资,先看现金流存款。有50W存款以上再考虑,车是消耗品,选适合自己的重要。你有钱就当我没说过
点赞 评论 收藏
分享
评论
26
13
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务