Leetcode常見鏈表問題及代碼示例
按規(guī)定區(qū)間反轉(zhuǎn)鏈表
思路:可以考慮成一種把前后數(shù)字的結(jié)點(diǎn)斷開重新組合的問題
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* reverseBetween(ListNode* head, int m, int n) { ListNode *dummy = new ListNode(-1), *pre = dummy; dummy->next = head; for (int i = 0; i < m - 1; ++i) pre = pre->next; ListNode *cur = pre->next; for (int i = m; i < n; ++i) { ListNode *t = cur->next; cur->next = t->next; t->next = pre->next; pre->next = t; } return dummy->next; } };
分割鏈表
思路:先找到一個(gè)大于或者等于給定值的節(jié)點(diǎn),然后再逐個(gè)把小于他們的值放在前面。例如本例先找到4,然后再找到3,然后把小于3的值都放在其前面
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* partition(ListNode* head, int x) { ListNode *p=new ListNode(-1); p->next=head; ListNode *pre=p,*cur=head; while(pre->next&&pre->next->val<x) pre=pre->next; cur=pre; while(cur->next){ if(cur->next->val<x){ ListNode *tmp=cur->next; cur->next=tmp->next; tmp->next=pre->next; pre->next=tmp; pre=pre->next; }else{ cur=cur->next; } } return p->next; } };
逆序鏈表存儲(chǔ)數(shù)相加
思路:先建立一個(gè)p結(jié)點(diǎn),然后將相加生成的新結(jié)點(diǎn)按順序放到p結(jié)點(diǎn)之后,然后再用一個(gè)新指針cur指向新鏈表的最后一位。設(shè)置一個(gè)進(jìn)位計(jì)數(shù)res,當(dāng)兩個(gè)結(jié)點(diǎn)值相加之后,可以用sum/10來表示進(jìn)位,然后以sum%10來建立新的結(jié)點(diǎn)。最后需要注意的是最高位的進(jìn)位問題,所以while結(jié)束后要,如果res為1,則再建一個(gè)值為1的結(jié)點(diǎn)。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { ListNode *p=new ListNode(-1),*cur=p; int res=0; while(l1||l2){ int val1=l1?l1->val:0; int val2=l2?l2->val:0; int sum=val1+val2+res; res=sum/10; cur->next=new ListNode(sum%10); cur=cur->next; if(l1) l1=l1->next; if(l2) l2=l2->next; } if(res) cur->next=new ListNode(1); return p->next; } };
順序鏈表存儲(chǔ)相加
思路:這道題和第2題類似,但是鏈表是從前往后遍歷,加法卻要從最低位相加,所以可以考慮改用棧來存儲(chǔ)放進(jìn)來的數(shù)據(jù)。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { stack<int> s1, s2; while (l1) { s1.push(l1->val); l1 = l1->next; } while (l2) { s2.push(l2->val); l2 = l2->next; } int sum = 0; ListNode *res = new ListNode(0); while (!s1.empty() || !s2.empty()) { if (!s1.empty()) { sum += s1.top(); s1.pop(); } if (!s2.empty()) { sum += s2.top(); s2.pop(); } res->val = sum % 10; ListNode *cur = new ListNode(sum / 10); cur->next = res; res = cur; sum /= 10; } return res->val == 0 ? res->next : res; } };
移除鏈表元素
思路:直接遞歸調(diào)用到鏈表末尾,然后回來,需要?jiǎng)h除的元素將鏈表next指針指向下一個(gè)元素即好。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* removeElements(ListNode* head, int val) { if(!head) return NULL; head->next=removeElements(head->next,val); return head->val==val?head->next:head; } };
刪除排序鏈表中的重復(fù)元素
思路:遞歸查找,如果head的值存在且相等,那么while循環(huán)跳過后面所有值相等的結(jié)點(diǎn),如果后面if還有值相等則繼續(xù)進(jìn)行遞歸。如果最后到head的值不同后,返回到head即可。<這種方式比新建鏈表存儲(chǔ)時(shí)間負(fù)責(zé)度高很多>
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* deleteDuplicates(ListNode* head) { if (!head) return head; if (head->next && head->val == head->next->val) { while (head->next && head->val == head->next->val) { head = head->next; } return deleteDuplicates(head->next); } head->next = deleteDuplicates(head->next); return head; } };
刪除順序鏈表中的重復(fù)元素
思路:head結(jié)點(diǎn)的值和身后結(jié)點(diǎn)的值進(jìn)行比較,如果值相同,則返回后面一個(gè)結(jié)點(diǎn)。最后回溯遞歸調(diào)用刪除重復(fù)結(jié)點(diǎn)。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* deleteDuplicates(ListNode* head) { if(!head||!head->next) return head; head->next=deleteDuplicates(head->next); return (head->val==head->next->val)?head->next:head; } };
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java GUI編程之貪吃蛇游戲簡單實(shí)現(xiàn)方法【附demo源碼下載】
這篇文章主要介紹了Java GUI編程之貪吃蛇游戲簡單實(shí)現(xiàn)方法,詳細(xì)分析了貪吃蛇游戲的具體實(shí)現(xiàn)步驟與相關(guān)注意事項(xiàng),并附帶demo源碼供讀者下載參考,需要的朋友可以參考下2017-09-09使用Spring?Retry實(shí)現(xiàn)業(yè)務(wù)異常重試
在系統(tǒng)中經(jīng)常遇到業(yè)務(wù)重試的邏輯,比如三方接口調(diào)用,timeout重試三遍,異常處理重試的兜底邏輯等,本文給大家介紹一下如何使用Spring?Retry優(yōu)雅的實(shí)現(xiàn)業(yè)務(wù)異常重試,需要的朋友可以參考下2024-01-01Java實(shí)現(xiàn)簡單的socket通信教程
這篇文章主要介紹了Java實(shí)現(xiàn)簡單的socket通信教程,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12VerifyCodeServlet(一次性驗(yàn)證碼)
這篇文章主要介紹了VerifyCodeServlet一次性驗(yàn)證碼的使用方法2017-05-05Spring @Value如何通過${}、#{}注入不同類型的值
這篇文章主要介紹了Spring @Value如何通過${}、#{}注入不同類型的值問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05Mybatis下動(dòng)態(tài)sql中##和$$的區(qū)別講解
今天小編就為大家分享一篇關(guān)于Mybatis下動(dòng)態(tài)sql中##和$$的區(qū)別講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-03-03