【绝知此事要躬行】线性表之链表OJ(上)
線(xiàn)性表之鏈表OJ(上)
“海鷗不再眷戀大海,可以飛更遠(yuǎn)” ——《明明就》
Hello,我們又見(jiàn)面啦!!!😊
筆者作為一個(gè)剛剛?cè)腴T(mén)的小白,鏈表還是一個(gè)前期頗有挑戰(zhàn)性的專(zhuān)題。
所以關(guān)于鏈表OJ題,我打算分三篇博客進(jìn)行一個(gè)分享,上下兩篇以及后續(xù)一個(gè)環(huán)形鏈表的專(zhuān)題。
(上):主要是一些鏈表的基本操作,難度一般。
(下):相較于(上),鏈表帶上了一些性質(zhì),難度會(huì)提高。
環(huán)形鏈表專(zhuān)題:主要是認(rèn)識(shí)一下環(huán)形鏈表,學(xué)習(xí)一下環(huán)形鏈表的操作,涉及一些證明,難度在三篇中是最高的。
博主建議:先不要看題解,自己把題目做一遍。這樣效果更好哦
**GO!GO!GO!讓我們進(jìn)入正題!**😉
1. 移除鏈表元素
題目鏈接:203. 移除鏈表元素(leetcode)
**題目描述:**給你一個(gè)鏈表的頭節(jié)點(diǎn) head 和一個(gè)整數(shù) val ,請(qǐng)你刪除鏈表中所有滿(mǎn)足 Node.val == val 的節(jié)點(diǎn),并返回 新的頭節(jié)點(diǎn) 。
圖示:
題解代碼:
typedef struct ListNode Node; struct ListNode* removeElements(struct ListNode* head, int val) {Node *prev=NULL,*cur=head,*next;while(cur){next = cur->next;if(cur->val==val){if(!prev)head=head->next;elseprev->next=cur->next;free(cur);}elseprev=cur;cur=next;}return head; }注意我們沒(méi)有用哨兵節(jié)點(diǎn),所以在刪除時(shí),需要注意頭刪的邏輯
2. 反轉(zhuǎn)鏈表
題目鏈接:206. 反轉(zhuǎn)鏈表leetcode
**題目描述:**給你單鏈表的頭節(jié)點(diǎn) head ,請(qǐng)你反轉(zhuǎn)鏈表,并返回反轉(zhuǎn)后的鏈表。
圖示:
需要注意的是,我們此處翻轉(zhuǎn)鏈表是對(duì)于原鏈表的節(jié)點(diǎn)進(jìn)行操作,諸如遍歷鏈表把數(shù)據(jù)放在數(shù)組中,逆序再建一個(gè)鏈表的方法均不符合題意。
2.1 循環(huán)迭代的寫(xiě)法
typedef struct ListNode Node; struct ListNode* reverseList(struct ListNode* head) {Node *prev=NULL,*cur=head,*next;while(cur){next=cur->next;cur->next=prev;prev=cur;cur=next;}return prev; }注意line 7 - 10 的順序,也就是反轉(zhuǎn)的邏輯!
2.2 遞歸的寫(xiě)法
ListNode* reverse(ListNode *prev,ListNode* cur) {if(cur==NULL) return prev; //遞歸出口ListNode *temp=cur->next;cur->next=prev;return reverse(cur,temp); }ListNode* reverseList(ListNode* head){return reverse(NULL,head);} };3. 找鏈表的中間節(jié)點(diǎn)
題目鏈接:876. 鏈表的中間結(jié)點(diǎn)
**題目描述:**給定一個(gè)頭結(jié)點(diǎn)為 head 的非空單鏈表,返回鏈表的中間結(jié)點(diǎn)。
如果有兩個(gè)中間結(jié)點(diǎn),則返回第二個(gè)中間結(jié)點(diǎn)。
這道題我們來(lái)初始一下==快慢指針==法:
其實(shí)直觀上很容易理解,快指針的“速度”為慢指針的兩倍,當(dāng)快指針走到頭時(shí),慢指針正好走到一半的位置。
結(jié)合圖像我們來(lái)理解一下:
代碼實(shí)現(xiàn):
typedef struct ListNode Node; struct ListNode* middleNode(struct ListNode* head) {Node *fast,*slow;fast=slow=head;while(fast&&fast->next){fast=fast->next->next;slow=slow->next;}return slow; }**思考題:循環(huán)條件能不能寫(xiě)成fast->next&&fast?為什么?**🤔
4.鏈表中倒數(shù)第k個(gè)節(jié)點(diǎn)
題目鏈接:[鏈表中倒數(shù)第k個(gè)結(jié)點(diǎn)](鏈表中倒數(shù)第k個(gè)結(jié)點(diǎn)_牛客題霸_??途W(wǎng) (nowcoder.com))
**題目描述:**輸入一個(gè)鏈表,輸出該鏈表中倒數(shù)第k個(gè)結(jié)點(diǎn)。如果k>鏈表長(zhǎng)度,返回NULL
這道題其實(shí)和上題比較類(lèi)似,主要我們不知道鏈表長(zhǎng)度,無(wú)法確定倒數(shù)第k到底在哪。
這邊我們也是用==快慢指針==解決:
快指針始終領(lǐng)先慢指針k步,當(dāng)快指針走到尾時(shí),慢指針即為倒數(shù)第k個(gè)節(jié)點(diǎn)
代碼實(shí)現(xiàn):
typedef struct ListNode Node; struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {Node *fast,*slow;fast=slow=pListHead;while(k--){if(!fast) return NULL;fast=fast->next;}while(fast){fast=fast->next;slow=slow->next;}return slow; }5.合并兩個(gè)有序鏈表
題目鏈接:21. 合并兩個(gè)有序鏈表
題目描述:將兩個(gè)升序鏈表合并為一個(gè)新的 升序 鏈表并返回。新鏈表是通過(guò)拼接給定的兩個(gè)鏈表的所有節(jié)點(diǎn)組成的。
圖示:
思路類(lèi)似歸并兩個(gè)有序數(shù)組,注意這邊要對(duì)原來(lái)的節(jié)點(diǎn)進(jìn)行操作
這邊建議運(yùn)用哨兵節(jié)點(diǎn)來(lái)簡(jiǎn)化我們放入節(jié)點(diǎn)的邏輯
typedef struct ListNode Node; struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {Node* head=(Node*)malloc(sizeof(Node)),*tail=head;//head->next=list1->val<list2->val?list1:list2;while(list1&&list2){if(list1->val<list2->val){tail->next=list1;tail=list1;list1=list1->next;}else{tail->next=list2;tail=list2;list2=list2->next;}}if(!list1) tail->next=list2;if(!list2) tail->next=list1;Node* rethead=head->next;free(head);return rethead; }!!與歸并數(shù)組時(shí)不同的是,while循環(huán)后兩個(gè)鏈表必定是一個(gè)表的節(jié)點(diǎn)全部放入了歸并后的鏈表,另一個(gè)表的節(jié)點(diǎn)還未全部放入到歸并后的鏈表。
故while循環(huán)后需要再把這些節(jié)點(diǎn)放入,這時(shí)我們就不需要一個(gè)節(jié)點(diǎn)一個(gè)節(jié)點(diǎn)放入,直接把list連到tail后面即可(后續(xù)節(jié)點(diǎn)都連在一起啦)
注意哪個(gè)空就要連另一個(gè)哦
🤗到此我們這博客也接近尾聲啦。
😊怎么樣感覺(jué)難度是不是還好,這篇還只是開(kāi)胃菜,下期難度up,up🤩
😊希望大家能在閱讀完后有所收獲!!!這將是對(duì)我最大的激勵(lì)!
敲代碼,碼字,作圖不易,期待一個(gè)小小的點(diǎn)贊??
如果你對(duì)博客內(nèi)容有什么疑惑,或者對(duì)思考題有什么不解,很歡迎大家來(lái)和我交流討論哦?
本期所有的代碼我將傳到我的gitee倉(cāng)庫(kù)中,如有需要可自行下載
倉(cāng)庫(kù)傳送門(mén):數(shù)據(jù)結(jié)構(gòu)
我們下篇博客見(jiàn)!😘
總結(jié)
以上是生活随笔為你收集整理的【绝知此事要躬行】线性表之链表OJ(上)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: FPGA基础知识2(Xilinx Alt
- 下一篇: SCANDY让你的手机变成扫描仪