206. 反转链表

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* reverseList(struct ListNode* head){
    struct ListNode *cur = head;
    struct ListNode *tail = NULL;
    struct ListNode *temp = NULL;

    while(cur != NULL){
        temp = cur->next;//保存下一个结点
        cur->next = tail;//确定当前结点的next结点,也就是确定新链表的尾结点
        tail = cur;//确定新链表的头结点
        cur = temp;//确定下一个需要处理的结点
    }

    return tail;
}
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode cur = head;
        ListNode tail=null;
        ListNode temp=null;
        while (cur != null) {
            temp = cur.next;
            cur.next = tail;
            tail = cur;
            cur = temp;
        }
        return tail;

    }
}

这一题属于逻辑题。要弄清楚先后顺序。

肯定是要遍历链表的。
那么就看怎么处理这些结点的关系了。主要看如何处理当前结点和下一个结点的关系了。
那我们来看该怎么处理。

一般来说,题目给出的链表头结点,我们不要去动它。然后我们就有两种策略了:

  • 第一种,使用一个变量指向head
  • 第二种,new一个新的结点,使其next指向head。

两种策略要根据需要自行选择。
本题,我们使用第一种。

因为我们需要直接遍历这个链表,所以直接使用cur这个变量直接指向head。我们接下来操作这个cur变量就可以了。(cur是current的缩写,表示当前的意思)

对于本题,反转,意味着使前后结点的关系发生改变。
那么肯定需要同时持有两个结点。
所以,我们在处理cur之前,肯定要持有cur后面的一个结点。
那么我们就需要一个temp变量来持有cur.next:

temp=cur.next;

好了。现在我们持有了cur指向了head,temp指向了head.next。
接下来:
我们需要让第一个结点(也就是当前结点的next指向null,因为是第一个结点,所以反转后,第一个结点肯定就变成最后一个结点了,新链表的最后一个结点的next肯定是null)

此外,我们还需要注意一点,遍历链表的过程中,需要把temp(cur)的结点next应该要指向新链表的头结点。

那么我们需要怎么来表示这个新链表的头结点呢??

目前的cur还是在链表的左侧,temp在链表的右侧。现在cur的next还是temp

这里我们需要引入一个新的变量,使其作为新链表的头结点。使用pre表示。pre=null;
pre一开始是新链表的头结点(此时它只是一个指针,无实际内存),这个pre就是cur的next,这个时候cur.next就是pre了(cur.next=pre),这样,cur就变成新链表的第一个结点了。
然后使pre替换cur,pre=cur;

这个时候注意,已经存在两个链表了,即pre(cur)的新链表,和temp打头的旧链表。目前两个链表没有任何关系了。

重要的一步来了,我们让cur指向temp的结点上。

null<-[pre] [cur]->[]->[]

上面就是两个链表的表示形式。

现在我们继续循环处理cur就可以了
null<-[]<-[pre] [cur]->[]

主要的难点是设置一个pre作为新链表的头。
初始化的时候pre是指向null的,而不是new出来的一个新结点。

posted @ 2021-06-10 23:08  头上有多云  阅读(78)  评论(0编辑  收藏  举报