网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
1、移除链表元素
- 链接直达:
- 题目:
- 思路:
此题要综合考虑多种情况,常规情况就如同示例1,有多个节点,并且val不连续,但是非常规呢?当val连续呢?当头部就是val呢?所以要分类讨论
常规情况:
需要定义两个指针prev和cur,cur指向第一个数据,prev指向cur的前一个。依次遍历cur指向的数据是否为val,若是,则把prev的下一个节点指向cur的下一个节点上,cur=cur->next,prev跟着cur一起走,直到cur走到NULL
连续val:
当我们仔细观察下,不难发现,在常规情况下是可以解决连续val的,但是头部val就不可了
头部val:
此时除了刚才定义的两个指针prev和cur外,还要有个head指向头部,当头部是val时,将cur指向下一个位置,head跟着一起动,直到cur指向的数据不为val时,将head赋给prev。此时剩余的就按常规处理即可。
- 代码如下:
struct ListNode* removeElements(struct ListNode* head, int val){ struct ListNode*cur=head; struct ListNode*prev=NULL; while(cur) { if(cur->val!=val) { prev=cur; cur=cur->next; } else { struct ListNode*next=cur->next; if(prev==NULL) { free(cur); cur=next; head=next; } else { prev->next=cur->next; free(cur); cur=prev->next; } } } return head; }
2、反转链表
- 链接直达:
- 题目:
- 思路:
**法一:**三指针翻转方向
定义三个指针n1,n2,n3分别用来指向NULL,第一个数据,第二个数据。让n2的next指向n1,把n2赋给n1,再把n3赋给n2,再执行n3=n3->next的操作,接下来重复上述操作,直到n2指向空即可。但是要注意,要先判断该链表是否为NULL,如果是,则返回NULL,此外,还要保证当n3为空时就不要动了,直接把n3赋给n2即可。
- 代码如下:
struct ListNode* reverseList(struct ListNode* head){ if(head==NULL) { return NULL; } struct ListNode*n1=NULL; struct ListNode*n2=head; struct ListNode*n3=n2->next; while(n2) { n2->next=n1; n1=n2; n2=n3; if(n3) { n3=n3->next; } } return n1; }
**法二:**头插
此法就需要再创建一个链表了,创建一个新的头部newhead指向NULL,再定义一个指针cur指向原链表第一个数据,注意还得定义一个指针next指向cur的下一个节点。遍历原链表,把节点取下来头插到newhead所在的链表。每次更新newhead赋给cur,如图所示:
- 代码如下:
struct ListNode* reverseList(struct ListNode* head){ if(head==NULL) { return NULL; } struct ListNode*cur=head; struct ListNode*next=cur->next; struct ListNode*newhead=NULL; while(cur) { cur->next=newhead; newhead=cur; cur=next; if(next) { next=next->next; } } return newhead; }
3、链表的中间节点
- 链接直达:
- 题目:
- 思路:
快慢指针
这道题要注意奇偶数,如果为奇数,如示例1,那么中间节点值就是3,反之偶数如示例2,返回第二个中间节点。此题我们定义两个指针slow和fast都指向第一个数据的位置,区别在于让slow一次走1步,fast一次走2步。当fast走到尾指针时,slow就是中间节点
- 代码如下:
struct ListNode* middleNode(struct ListNode* head){ struct ListNode*slow=head; struct ListNode*fast=head; while(fast&&fast->next) { slow=slow->next; fast=fast->next->next; } return slow; }
4、链表中倒数第k个节点
- 链接直达:
- 题目:
- 思路:
快慢指针
定义两个指针slow和fast,让fast先走k步,再让slow和fast同时走,当fast走到尾部时,slow就是倒数第k个,因为这样的话slow和fast的差距始终是k个,当fast走到空时结束。此题同样可以走k-1步,不过当fast走到尾部时结束,也就是fast的下一个节点指向空时结束,都一样。先拿走k步举例,如图所示:
- 代码如下:
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) { // write code here struct ListNode*fast=pListHead; struct ListNode*slow=pListHead; while(k--) { //if判断,防止k大于链表的长度 if(fast==NULL) return NULL; fast=fast->next; } while(fast) { fast=fast->next; slow=slow->next; } return slow; }
5、合并两个有序链表
- 链接直达:
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-J4coVAo3-1715765693109)]
[外链图片转存中…(img-vd6rOiR5-1715765693110)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!