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* removeElements(ListNode* head, int val) { ListNode *L=new ListNode(-1); L->next=head; ListNode *slow=L,*fast=head,*r=L; while(fast!=nullptr) { if(fast->val==val) { slow->next=fast->next; fast=slow->next; } else{ fast=fast->next; slow=slow->next; } } return L->next; } };
跟一刷写法不太一样,一开始忘记slow->next=nullptr报错
/** * 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* removeElements(ListNode* head, int val) { ListNode *L=new ListNode(-1); L->next=head; ListNode *slow=L,*fast=L->next; if(head==nullptr) { return head; } while(fast!=nullptr) { if(fast->val==val) { fast=fast->next; } else { slow->next=fast; slow=slow->next; fast=fast->next; } } slow->next=nullptr; return L->next; } };
707. 设计链表
链接:力扣
二刷感觉比一刷理解的更深刻了。
期间用了尾指针,但是发现hold不住。只能尾插时从头开始找到尾再插入。
另外其实一些函数有出错,所以另外写了print函数,每一步都打印链表进行调试。
巧用了while(p!=nullptr && index) ,每次想着index=0,index=1进行写
class MyLinkedList { public: struct ListNode{ int val; ListNode *next=nullptr; ListNode(int val):val(val),next(nullptr){}; }; MyLinkedList() {//构造函数,初始化头节点 //初始化头节点 L=new ListNode(-1); // r=L;//尾指针 } void print_L(ListNode *L) { ListNode *p=L->next; while(p!=nullptr) { cout<<p->val<<" "; p=p->next; } cout<<endl; } int get(int index) { ListNode *p=L->next; while(p!=nullptr && index) { p=p->next; index--; } if(p!=nullptr) { return p->val; } // print_L(L); return -1; } void addAtHead(int val) {//头插法 ListNode *temp=new ListNode(val); temp->next=L->next; L->next=temp; // print_L(L); } void addAtTail(int val) {//尾插法 ListNode *temp=new ListNode(val); ListNode *r=L; while(r->next!=nullptr) { r=r->next; } r->next=temp; //print_L(L); } void addAtIndex(int index, int val) { //假设index=0,=1 ListNode *p=L; ListNode *temp=new ListNode(val); //将一个值为 val 的节点插入到链表中下标为 index 的节点之前 while(p!=nullptr && index) { p=p->next; index--; } if(p!=nullptr)//如果 index 比长度更大,该节点将 不会插入 到链表中 { temp->next=p->next; p->next=temp; } //print_L(L); } void deleteAtIndex(int index) { //如果要删除节点,首先节点要存在 ListNode *pre=L; while(pre!=nullptr && index) { pre=pre->next; index--; } if(pre==nullptr) { //没有什么好删的 } else if(pre!=nullptr && pre->next==nullptr) { //没有什么好删的 } else { pre->next=pre->next->next; } // print_L(L); } private: ListNode *L=nullptr;//L为头节点 // ListNode *r=nullptr; 不太好掌握,废了 }; /** * Your MyLinkedList object will be instantiated and called as such: * MyLinkedList* obj = new MyLinkedList(); * int param_1 = obj->get(index); * obj->addAtHead(val); * obj->addAtTail(val); * obj->addAtIndex(index,val); * obj->deleteAtIndex(index); */
206.反转链表
链接:力扣
二刷还是各种报错,最主要的是忘记了一刷的简便算法
二刷的错误点在于边界判断太多了,而且一开始的慢指针尾巴忘记指向空指针,导致整个链表没有尾巴,一直报错了十分钟。
/** * 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 *slow=head; //忘记写slow->next==nullptr,导致反转后的链表没有尾巴 ListNode *fast=head->next; slow->next=nullptr; while(fast!=nullptr && fast->next!=nullptr) { ListNode *temp=fast; fast=fast->next; temp->next=slow; slow=temp; } if(fast!=nullptr) { fast->next=slow; return fast; } return head; } };
回忆一刷的简单做法,直接让slow指针从空开始,fast从head开始.
/** * 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) { return nullptr; } ListNode *slow=nullptr,*fast=head; while(fast!=nullptr) { ListNode *temp=fast; fast=fast->next; temp->next=slow; slow=temp; } return slow; } };
24. 两两交换链表中的节点
链接:力扣
基本还是搞错了,cur 和 temp temp1 三个指针 四个节点,相隔距离,链接关系,都是需要稍微死记硬背一点的。
/** * 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 { /*再看一遍我也只是跟着过一遍。 重点 cur temp temp1 三个指针交叉成一个均匀的麻花,涉及四个节点,三个指针分别指向1、2、4节点 最后cur=temp,每次前进一步 */ public: ListNode* swapPairs(ListNode* head) { if(head==nullptr || head->next==nullptr)//只有0个或者1个节点 { return head; } //两个及以上节点,可以交换 ListNode *L=new ListNode(-1); L->next=head; ListNode *cur=L,*temp=nullptr,*temp1=nullptr; while(cur!=nullptr && cur->next!=nullptr && cur->next->next!=nullptr) { temp=cur->next; temp1=cur->next->next->next; cur->next=temp->next; cur->next->next=temp; temp->next=temp1; cur=temp;//每次只前进一步!!这里一开始写成了temp1 } return L->next; } };
19. 删除链表的倒数第 N 个结点
链接:力扣
十分尴尬,我已经忘了最佳的那种做法。。。。就是快慢指针那种。
对链表遍历了两遍。
二刷做法:
/** * 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* removeNthFromEnd(ListNode* head, int n) { //以第一个为例,删除倒数第2个节点,就是找倒数第三个节点==正数第三个节点,链表长度为5.意思是找到第len-n个节点即可 //第一步,创建头节点 ListNode *L=new ListNode(-1); L->next=head; //第二步,计算整个链表长度 ListNode *p=L->next; int len=0; while(p!=nullptr) { len++; p=p->next; } int k=len-n; p=L;//这一步很重要!一定要搞清楚!! while(p!=nullptr && k) { p=p->next; k--; } if(p!=nullptr && p->next!=nullptr) { p->next=p->next->next; } return L->next; } };
一刷,快慢指针最佳做法,重新写一遍.注意n++。fast和slow都从空的头节点开始,fast要先走n+1步
/** * 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 { /* 以第一个为例,删除链表的倒数第2个节点相当于找到正数第三个节点 3 2 n len-n 让fast指针先走n步,然后slow再和fast一起走 */ public: ListNode* removeNthFromEnd(ListNode* head, int n) { if(head==nullptr ) { return head; } ListNode *L=new ListNode(-1); L->next=head; ListNode *fast=L,*slow=L; n++; while(n && fast!=nullptr) { fast=fast->next; n--; } while(fast!=nullptr) { slow=slow->next; fast=fast->next; } if(slow!=nullptr && slow->next!=nullptr) { slow->next=slow->next->next; } return L->next; } };
面试题 02.07. 链表相交
链接:力扣
挺好的,看了以前写的那一遍,然后重写了一遍。只能说对于资质普通者,要重复刷题才行。
p1 、p2第一次遍历完后要从恢复到链表头开始遍历
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { ListNode *p1=headA,*p2=headB; int lenA=0,lenB=0; while(p1!=nullptr) { p1=p1->next; lenA++; } while(p2!=nullptr) { p2=p2->next; lenB++; } int len=lenA-lenB; // cout<<lenA<<" "<<lenB<<" "<<len<<endl; //重新从头开始遍历 p1=headA,p2=headB; if(lenA>=lenB) { while(len && p1!=nullptr) { p1=p1->next; // cout<<"p1 "<<p1->val<<endl; len--; } } else { len=-len; while(len && p2!=nullptr) { p2=p2->next; len--; } } while(p1!=nullptr && p2!=nullptr && p1!=p2) { p1=p1->next; p2=p2->next; } return p2; } };
142. 环形链表 II
链接:力扣
二刷发现思路记错了,fast一次走两步,slow一次走一步,我记成fast多走两步后,两个就同步了。确实如果fast只是先多走两步,那毫无意义,fast和slow永远差两步永远不会相交!!
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ /* 有一道题印象深刻,判断两个链表相交的位置。突然发现是这道题!真尴尬 基本思路: 先让fast节点多走两步,!!fast指针是一步走两个节点,slow指针一步走一个节点 然后fast和slow必然在环内相交。记住环内相交节点,然后让第三个指针从链表起始节点出发,相交节点指针和起始指针同步出发,来到环的入口节点 */ class Solution { public: ListNode *detectCycle(ListNode *head) { if(head==nullptr || head->next==nullptr) { return nullptr; } ListNode *fast=head,*slow=head; while(fast!=nullptr && fast->next!=nullptr) { slow=slow->next; fast=fast->next->next; if(slow==fast)//说明有环 { //cout<<"有环"<<endl; ListNode *p=head; while(p!=slow) { p=p->next; slow=slow->next; } return slow; } } return nullptr; } };