日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Leetcode初级算法(链表篇)

發布時間:2025/4/9 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Leetcode初级算法(链表篇) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

刪除鏈表的倒數第N個節點

感覺自己對于鏈表的知識還是了解的不夠深入,所以沒有想到用雙指針進行操作。我的想法是這樣的,首先計算整個鏈表的長度,然后遍歷到長度減去n的節點處,執行刪除操作。
自己的代碼:

/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Solution { public:ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode* cur=head;ListNode *cou=head;int i=0;int count=1;while(cou->next!=NULL){cou=cou->next;count++;}if(count==1) return NULL;if(count==n) {head=head->next;return head;}while(head->next!=NULL && i<count-1-n){head=head->next;i++;}if(head->next!=NULL){ListNode *temp;temp=head->next;head->next=temp->next;}return cur;} };

相信看過代碼后都會覺得這個代碼的邏輯比較奇怪,尤其是

if(count==1) return NULL; if(count==n) { head=head->next; return head; }

這段代碼,感覺是根據測試案例試出來的。的確是這樣的,我的代碼在[1,2]去掉倒數第二個元素或者[1,2,3]去掉倒數第三各元素的時候總是會去除中間的額元素,經排查原因應該是head節點的理解有些問題。我認為的head是頭指針,head->next才是第一個結點,但這代碼里的意思好像是head就已經是第一個節點了,所以在后面判斷的時候有些bug。當然我們還是習慣用比較常規的方法就是用雙指針的方法進行問題的解決:
這里放出大神的代碼:

class Solution{ public: ListNode* removeNthFromEnd(ListNode* head,int n){ if(!head->next) return NULL; LisNode *pre=head,*cur=head; for(int i=0;i<n;i++) cur=cur->next; if(!cur) return head->next; while(cur->next){ cur=cur->next; pre=pre->next; } pre->next=pre->next->next; return head; } };

下面我來解釋一下這段代碼的意思,定義了兩個指針,兩個指針相差n個距離,這樣的話當其中一個指針指向結尾處的時候,另一個指針就自然指向了我們需要刪除的前一個元素位置了,然后執行刪除操作,這樣非常的快捷。

反轉鏈表

感覺這道題有些帥,試著走了一遍邏輯,并不是像我之前以為的一個新鏈表然后反向遍歷讀出數據,但是這個邏輯是一次反轉一個,用到dummy始終指向頭結點、cur始終指向當前的節點、tmp指向下一個結點,邏輯就是將cur下一個指向tmp的下一個結點,將tmp指向頭結點,然后dummy再指向tmp,然后再次進行迭代。仔細思考一下這個反轉轉的真的很有智慧。代碼如下:

/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Solution { public:ListNode* reverseList(ListNode* head) {if(!head) return head;ListNode *dummy=new ListNode(-1);dummy->next=head;ListNode *cur=head;while(cur->next){ListNode *tmp=cur->next;cur->next=temp->next;tmp->next=dummy->next;dummy->next=tmp;}return dummy->next;} };

合并兩個有序鏈表

這題比較簡單,就是不斷地判斷;如果有一個鏈表已經比較晚了,則直接把后面所有的元素再加到新鏈表中就OK了。代碼如下:

/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Solution { public:ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {if(l1!=NULL&&l2==NULL) return l1;if(l1==NULL&&l2!=NULL) return l2;ListNode head(0); ListNode* l3=&head;while(l1!=NULL&&l2!=NULL){if(l1->val<l2->val){l3->next=l1;l1=l1->next;}else{l3->next=l2;l2=l2->next;}l3=l3->next;}if(l1!=NULL)l3->next=l1;if(l2!=NULL)l3->next=l2;return head.next;} };

回文鏈表

解釋在代碼注釋里了,感覺學到了一招快速到達鏈表的中央了(slow與fast的應用,fast->next->next是slow->next速度的兩倍,當fast->next指向結尾,slow指向中間!!)

/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Solution { public:bool isPalindrome(ListNode* head) {//O(n)時間表示不能有嵌套循環, O(1)空間表示不能再次添加新鏈表if(!head||!head->next) return true;ListNode *slow=head,*fast=head;stack<int> s;s.push(head->val);while(fast->next!=NULL && fast->next->next!=NULL){slow=slow->next;fast=fast=fast->next->next; //fast的速度是slow的兩倍,這樣就能保證slow最后能找到鏈表的中間s.push(slow->val);}if(fast->next==NULL)s.pop(); //說明是奇數個,中間的就不用進行比較了,所以直接pop掉比較后面的while(slow->next!=NULL){slow=slow->next;int tmp=s.top();s.pop();if(tmp!=slow->val) return false;}return true; } };

環形鏈表

環形鏈表是循環鏈表的最簡單形式,即首尾是相連的。所以若我們指定兩個指針,fast和slow。兩個指針同時從頭結點開始出發,fast指針走兩步,slow指針走一步;若鏈表有環,這兩個指針肯定會在某點相遇;若鏈表無環,fast會直接先到達NULL。因為不斷的循環,只要有環就一定會相遇,如果沒環則一定會存在NULL。
代碼如下:

/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Solution { public:bool hasCycle(ListNode *head) {ListNode *slow=head,*fast=head;while(fast!=NULL && fast->next!=NULL){slow=slow->next;fast=fast->next->next;if(slow==fast) return true;}return false;} };

轉載于:https://www.cnblogs.com/yunlambert/p/8847671.html

總結

以上是生活随笔為你收集整理的Leetcode初级算法(链表篇)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。