• 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出来的一个新结点。

  • 相关阅读:
    Mysql关键字冲突的解决方案
    js日期时间函数
    Mysql字符串字段中是否包含某个字符串,用 find_in_set
    mysql中 where in 用法
    Best of Best系列(4)——AAAI
    Best of Best系列(5)——IJCAI
    Best of Best系列(3)——ICML
    Best of Best系列(6)——SIGIR
    Best of Best系列(2)——ICCV
    Best of Best系列(1)——CVPR
  • 原文地址:https://www.cnblogs.com/dhu121/p/14873264.html
Copyright © 2020-2023  润新知