Leetcode_206_Reverse_Linked_List(反转链表)_easy

这一生的挚爱 提交于 2020-03-17 11:16:09

题目:

反转一个单链表。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

解题思路:

1. 迭代法:

从链表的头结点开始遍历链表,依次将节点的next指向节点前一个节点。

关键:要弄清楚prev,curr,next三者之前的关系。
重要部分:因为遍历链表时,要将当前节点curr.next指向当前节点的前一个节点prev,这样就没有办法继续遍历,所以要在这之前,将curr.next的地址值复制一份给ListNode tempNext。

public ListNode reverseList(ListNode head) {
    ListNode prev = null;
    ListNode curr = head;
    while (curr != null) {
        ListNode nextTemp = curr.next;
        curr.next = prev;
        prev = curr;
        curr = nextTemp;
    }
    return prev;
}

时间复杂度:O(n)
空间复杂度:O(1)

2. 头插法

思想和迭代法一模一样,迭代法里的prev就是newHead.next,都是null,只不过头插法新多了一个ListNode newHead = new ListNode(-1),让它的next = null, 所以代码里的prev都是以newHead.next出现。
个人觉得迭代法清洗明了,头插法反而搞复杂了。

public ListNode reverseList(ListNode head) {
    ListNode newHead = new ListNode(-1);
    while (head != null) {
        ListNode next = head.next;
        head.next = newHead.next;
        newHead.next = head;
        head = next;
    }
    return newHead.next;
}

时间复杂度:O(n)
空间复杂度:O(1)

3.递归法

递归执行过程:

  1. 在next=5=head; head.next=null,即返回head=5,并赋值给newHead前,一直调用递归语句:ListNode newHead = reverseList(next);前面的代码:
    if (head == null || head.next == null) {
        return head;
    }
    ListNode next = head.next;

此前递归栈存储的值为:
head next
4 5
3 4
2 3
1 2

  1. 当next=5=head; head.next=null,return = head=5,此时,递归结束,栈中的元素开始弹出,开始执行递归语句:ListNode newHead = reverseList(next);后面面的代码:
 next.next = head;
 head.next = null;
 return newHead;

5.next = 4 4.next = null
4.next = 3 3.next = null
3.next = 2 2.next = null
2.next = 1 1.next = null

  1. 栈中元素清空,返回newHead=5
public ListNode reverseList(ListNode head) {
    if (head == null || head.next == null) {
        return head;
    }
    ListNode next = head.next;
    ListNode newHead = reverseList(next);
    next.next = head;  // 反转
    head.next = null;
    return newHead;
}

时间复杂度:O(n)
空间复杂度:O(n)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!