LeetCode Notes_#206 Reverse Linked List(剑指Offer#24 反转链表)

LeetCode Notes_#206 Reverse Linked List(剑指Offer#24 反转链表)

Contents

题目

Reverse a singly linked list.

Example:

Input: 1->2->3->4->5->NULL
Output: 5->4->3->2->1->NULL

思路分析

思考

  • 为什么要使用两个指针?

    • 因为每次进行逆转操作必然涉及到两个节点,head(后)->next = new_head(前),所以必然是两个指针
    • 两个指针指向的就是当前操作到的两个相邻的节点,另一个角度来说,也可以看做
      1. 正在被拆分的原链表的头,命名为head;
      2. 正在被构造的新链表的头,命名为new_head;新链表往前延伸(这也有点和惯常思维不一样),好像一个栈,从顶部加入新元素,先加入的反而排在后面
    • 严格来说是三个,为了不断遍历,一开始还需要把head->next备份下来。正是由于指针有点多,所以很容易糊涂。要时刻明确每一个指针存在的意义。
  • 写循环的思路?

    • 循环条件是什么?
      • 遍历到链表的最后
    • 循环体是什么?
      • 先考虑中间的情况(普遍),再去考虑头和尾的情况(特殊)
    • 用哪一种循环(for还是while?)
      • 因为不确定循环次数,所以是while

每次循环的操作
每次循环的操作

  • 关于链表的头指针?

解答

C++

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* new_head = NULL;
        while(head){
            ListNode* next = head->next;
            head->next = new_head;
            new_head = head;
            head = next;
        }
        return new_head;
        
    }
};

Python

class Solution(object):
    def reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        new_head = None
        while(head):
            next = head.next
            head.next = new_head
            new_head = head
            head = next
        return new_head

Java迭代法

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode newHead = null;
        //head:旧链表的头,由于头部的节点不断地被放到新链表,所以相当于是取旧链表的头节点
        //newHead:新链表的头,由于新链表在头部不断增加新节点,所以就是取每次新增加的那个头节点
        //next:保存当前head的下一个节点,head断开旧链表后,用next更新新的head
        //以上三个节点在同一时间是相邻的:newHead->head->next
        while(head != null){
            ListNode next = head.next;
            head.next = newHead;//将链表当前第一个节点断开,连接到新链表的头部
            newHead = head;//更新新链表头部为head,因为head也连接到新链表当中了
            head = next;//head更新为旧链表的第一个节点,也就是刚才保存的next
        }
        return newHead;
    }
}

Java递归法

有点分治法的意思,提前保存一个cur变量,同时阻塞住程序,递归函数会一直向后遍历,直到head.next==null,此时返回最后一个节点,开始回溯。
回溯的过程只处理一个指针,把head和head.next之间的指针反转。

class Solution {
    public ListNode reverseList(ListNode head) {
        //输入head为null
        if(head == null) return null;
        //递归
        if(head.next == null) return head;
        ListNode cur = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return cur;
    }
}
posted @ 2019-01-10 18:39  Howfar's  阅读(154)  评论(0编辑  收藏  举报