首页 > 其他分享 >Day2 链表

Day2 链表

时间:2024-04-06 20:00:31浏览次数:20  
标签:head ListNode val nullptr Day2 next 链表 front

排序算法,手撕快排,二分查找要整理刷一遍

206. 反转链表

双指针法

自己的写的,用tmp保存下一个开始的节点;先移动慢指针,再移动快指针。

 /**
  * Definition for singly-linked list.
  * struct ListNode {
  *     int val;
  *     ListNode *next;
  *     ListNode() : val(0), next(nullptr) {}
  *     ListNode(int x) : val(x), next(nullptr) {}
  *     ListNode(int x, ListNode *next) : val(x), next(next) {}
  * };
  */
 class Solution {
 public:
     ListNode* reverseList(ListNode* head) {
         if(head==nullptr || head->next==nullptr){
             return head;
        }
         ListNode* front=head->next;
         ListNode* behind=head;
 ​
         ListNode* tmp=front->next;
         front->next=behind;
         behind->next=nullptr;   //第一个翻转后尾指针是nullptr
         behind=front;
         front=tmp;
 ​
         while(front!=nullptr){
             tmp=front->next;
             front->next=behind;
             behind=front;
             front=tmp;
        }
         return behind;  //返回尾指针,因为while条件是front指向null,所以头指针是behind
    }
 };

从头结点开始,慢指针从null开始,这样就不用重复写了。

 /**
  * Definition for singly-linked list.
  * struct ListNode {
  *     int val;
  *     ListNode *next;
  *     ListNode() : val(0), next(nullptr) {}
  *     ListNode(int x) : val(x), next(nullptr) {}
  *     ListNode(int x, ListNode *next) : val(x), next(next) {}
  * };
  */
 class Solution {
 public:
     ListNode* reverseList(ListNode* head) {
         if(head==nullptr || head->next==nullptr){   //空链表,或只有头节点的链表,不必翻转
             return head;
        }
         ListNode* front=head;
         ListNode* behind=nullptr;
         ListNode* tmp;
         
         while(front!=nullptr){  
             tmp=front->next;
             front->next=behind;
             behind=front;
             front=tmp;
        }
         return behind;  //返回尾指针,因为while条件是front指向null,所以头指针是behind
    }
 };

递归法

自己的思路:

递归法:

  1. 终止条件

  2. 重复的部分(原子操作)--只针对两个节点的情况,剩下的都翻转好了

没写好的

 /**
  * Definition for singly-linked list.
  * struct ListNode {
  *     int val;
  *     ListNode *next;
  *     ListNode() : val(0), next(nullptr) {}
  *     ListNode(int x) : val(x), next(nullptr) {}
  *     ListNode(int x, ListNode *next) : val(x), next(next) {}
  * };
  */
 class Solution {
 public:
     ListNode* reverseList(ListNode* head) {
         //终止条件,空/仅有头指针
         if(head==nullptr || head->next==nullptr){
             return head;
        }
 ​
         // ListNode* front=head;
         // ListNode* behind=nullptr;
         // ListNode* front;
         // ListNode* behind;
 ​
         ListNode* tmp=front->next;
         front->next=behind;
         behind=front;
         front=reverseList(head->next);
         return front;    
 ​
    }
 };

修改后的

 /**
  * Definition for singly-linked list.
  * struct ListNode {
  *     int val;
  *     ListNode *next;
  *     ListNode() : val(0), next(nullptr) {}
  *     ListNode(int x) : val(x), next(nullptr) {}
  *     ListNode(int x, ListNode *next) : val(x), next(next) {}
  * };
  */
 class Solution {
 public:
     ListNode* reverseList(ListNode* head) {
         //终止条件,空/仅有头指针
         if(head==nullptr || head->next==nullptr){
             return head;
        }        
         ListNode* newhead=reverseList(head->next);  //倒数第二个节点为头节点的链表,已经翻转好了
         //仅处理两个节点的情况
         head->next->next=head;
         head->next=nullptr;
 ​
         return newhead;    
    }
 };

环形链表

快慢指针,数学计算

思路:

  1. 判断是否有环?

    • 终止条件:无环时遍历完链表 while(fast!=nullptr && fast->next!=nullptr)

  2. 若有环,则计算入口。

    • x=z,当多走一圈时

    • (x+y)*2 = x+y+(y+z)*n,n=1时,x=z

实现:

  1. 快指针一次走两步,慢指针一次走一步。快指针一定先进入环。

  2. 计算环入口

 /**
  * Definition for singly-linked list.
  * struct ListNode {
  *     int val;
  *     ListNode *next;
  *     ListNode(int x) : val(x), next(NULL) {}
  * };
  */
 class Solution {
 public:
     ListNode *detectCycle(ListNode *head) {
         ListNode* fast=head;
         ListNode* slow=head;
 ​
         while(fast!=nullptr && fast->next!=nullptr){    //遍历完链表结束
             fast=fast->next->next;  //因为一次走两步,所以要提前检查fast->next是否为空指针,否则报错
             slow=slow->next;    //slow一次走一步
             if(fast==slow){ //从相遇的地方开始,记录fast slow相遇的地方
                 ListNode* x=head;
                 ListNode* z=fast;
                 while(x!=z){
                     x=x->next;
                     z=z->next;
                }
                 return x; //相遇的地方是入口点
            }
        }
         return NULL;
       
               
    }
 };
 

标签:head,ListNode,val,nullptr,Day2,next,链表,front
From: https://www.cnblogs.com/good-mind/p/18117849

相关文章

  • Day2 第一章 数组part02
    1.977.有序数组的平方为什么‘非递减‘就是递增?暴力解法就是遍历数组挨个元素平方,之后再给数组排序,这里有时间复习一下各种排序的时间复杂度以及空间复杂度!在移除数组元素那道题里,涉及到位置变更以及要求时间复杂度为O(n),从这可以看到一点用双指针的规律,就是:指针设定为......
  • 深入理解Java异常处理机制(day20)
    异常处理异常处理是程序运行过程产生的异常情况进行恰当的处理技术在计算机编程里面,异常的情况比所我们所想的异常情况还要多。Java里面有两种异常处理方式;1.利用try···catch···finaly语句处理异常,优点是分开了处理异常代码和程序正常代码,增强了程序的可读性,减少......
  • leetcode.206.反转链表
    题目题意:反转一个单链表。示例:输入:1->2->3->4->5->NULL输出:5->4->3->2->1->NULL思路双指针:创建指针p,curr,初始分别指向null和头节点,每轮循环移动一个节点的指向,直到指到最后一个位置为止。递归法:基于双指针。注意递归的退出条件实现双指针classSolution{......
  • leetcode.面试题 02.07. 链表相交
    题目给你两个单链表的头节点headA和headB,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回null。图示两个链表在节点c1开始相交:思路假a在链表A上移动,b在链表B上移动,a移动完在B上开始,b移动完再A上开始。最终a移动的距离a+c+x,b移动的距......
  • Day1数组+链表
    数组while(不变量)--不变量循环704.二分查找https://leetcode.cn/problems/binary-search/题目要求数组升序无重复数字方法一-左闭右闭[]左闭右闭区间[left,right],若nums[middle]!=target,则边界一定不包含middle;用while循环,当找到了则直接返回,若没有则在while循......
  • C++链表小册子
    目录1.简记2.多说两句3.算法题1.简记对于C++链表类的创建,有以下简记:堆分配,new作为右值。返回指针。对象生命周期手动管理,需要显式删除(delete)ListNodedummy(0);栈分配,返回ListNode。仅在作用域内生效(和常见的初始化int一样)。要得到ListNode指针需要&取地址2.多说两句......
  • 书生·浦语大模型全链路开源体系——学习笔记day2&day3--纯纯新手入门
    学习链接:tutorial/helloworld/hello_world.mdatmain·InternLM/tutorial(github.com) 【精彩,照着做就能体验很多本来遥不可及的东西】笔记分享链接:https://github.com/InternLM/tutorial/discussions/37 本笔记定位是对学习链接的补充和小白发牢骚,希望大佬能愿意点评一......
  • LeetCode-142. 环形链表 II【哈希表 链表 双指针】
    LeetCode-142.环形链表II【哈希表链表双指针】题目描述:解题思路一:快慢指针判断是否有环见解题思路二:set()解题思路三:0题目描述:给定一个链表的头节点head,返回链表开始入环的第一个节点。如果链表无环,则返回null。如果链表中有某个节点,可以通过连续跟踪next......
  • 链表
    链表链表结构定义//链表结构定义typedefstructLNode{intdata;structLNode*next;}LNode,*LinkList;初始化链表//初始化链表boolInitList(LinkList&L){L=newLNode;L->next=nullptr;returntrue;}创建链表(头插法)//创建链......
  • 多种方法从尾部移除指定位置的链表节点
    连绵的春雨把人困在家乡,于是我继续开始刷着算法题,通过19.Remove年thNodeFromEndofList复习了一波链表的操作,这道题也是比较典型的链表问题,值得分享一下。题目如下所示:Giventheheadofalinkedlist,removethenthnodefromtheendofthelistandreturnitsh......