当前位置:   article > 正文

【数据结构与算法】---OJ手撕链表题

手撕链表题

作者:旧梦拾遗186

专栏:数据结构成长日记

每日励志:

你没资格半途而废,你没资格破罐子破摔,你只能让自己活得比任何人都好,比任何人都强大,你已经没有退路。

前言:

小编带大家学习链表OJ题。

目录

移除链表元素

题解

反转链表

题解

合并两个有序链表

题解:


移除链表元素

移除链表元素https://leetcode.cn/problems/remove-linked-list-elements/

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

示例 1:

输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]

示例 2:

输入:head = [], val = 1
输出:[]

示例 3:

输入:head = [7,7,7,7], val = 7
输出:[]

提示:

  • 列表中的节点数目在范围 [0, 104] 内
  • 1 <= Node.val <= 50
  • 0 <= val <= 50

题解

思路一:一种比较普遍的方式,边遍历边找不同。我们可以通过定义两个指针,一个指向头节点,一个置为NULL。当遇到值为相同的时候,直接跳过去。指向下一位。同时,我们要去注意头删的问题,因为题目中给出的函数具有头结点head。

  1. struct ListNode* removeElements(struct ListNode* head, int val){
  2. struct ListNode* cur=head;
  3. struct ListNode* pre=NULL;
  4. while(cur)
  5. {
  6. if(cur->val==val)
  7. {
  8. if(cur==head)
  9. {
  10. head=head->next;
  11. free(cur);
  12. cur=head;
  13. }
  14. else
  15. {
  16. pre->next=cur->next;
  17. free(cur);
  18. cur=pre->next;
  19. }
  20. }
  21. else
  22. {
  23. pre=cur;
  24. cur=cur->next;
  25. }
  26. }
  27. return head;
  28. }

 思路二:给一个新的链表,不是val的结点尾插到新链表即可。最后结点置为NULL。同时,还是要注意头结点的问题

  1. struct ListNode* removeElements(struct ListNode* head, int val){
  2. struct ListNode* cur=head;
  3. struct ListNode* tail=NULL;
  4. struct ListNode* newnode=NULL;
  5. while(cur)
  6. {
  7. if(cur->val!=val)
  8. {
  9. if(tail==NULL)
  10. {
  11. newnode=tail=cur;
  12. }
  13. else
  14. {
  15. tail->next=cur;
  16. tail=tail->next;
  17. }
  18. cur=cur->next;
  19. }
  20. else
  21. {
  22. struct ListNode* del=cur;
  23. cur=cur->next;
  24. free(del);
  25. }
  26. }
  27. if(tail)
  28. {
  29. tail->next=NULL;
  30. }
  31. return newnode;
  32. }

我们不难发现,如果没有头结点,我们都要去关注,所以我们可以给出带头结点(哨兵链表)的单链表来进行实现

  1. struct ListNode* removeElements(struct ListNode* head, int val){
  2. struct ListNode*cur = head;
  3. struct ListNode*guard = (struct ListNode*)malloc(sizeof(struct ListNode));
  4. struct ListNode*tail = guard;
  5. while(cur)
  6. {
  7. if(cur->val != val)
  8. {
  9. // tail=cur;
  10. tail->next = cur;
  11. tail = tail->next;
  12. cur = cur->next;
  13. }
  14. else
  15. {
  16. struct ListNode*del = cur;
  17. cur = cur->next;
  18. free(del);
  19. }
  20. }
  21. if(tail)
  22. tail->next = NULL;
  23. head = guard->next;
  24. free(guard);
  25. return head;
  26. }

有头结点之后我们就不需要去考虑删除第一个元素的事了。

反转链表

反转链表https://leetcode.cn/problems/reverse-linked-list/

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
 

示例 1:


输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例 2:


输入:head = [1,2]
输出:[2,1]
示例 3:

输入:head = []
输出:[]
 

提示:

链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000
 

进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?

题解

思路一:取结点头插到新的结点

  1. struct ListNode* reverseList(struct ListNode* head){
  2. struct ListNode* cur=head;
  3. struct ListNode* newhead=NULL;
  4. while(cur)
  5. {
  6. struct ListNode* next=cur->next;
  7. cur->next=newhead;
  8. newhead=cur;
  9. cur=next;
  10. }
  11. return newhead;
  12. }

 

思路二:直接把指针的方向进行翻转即可,使得链表翻转

  1. struct ListNode* reverseList(struct ListNode* head){
  2. struct ListNode* cur=head;
  3. struct ListNode* pre=NULL;
  4. while(cur)
  5. {
  6. struct ListNode* next=cur->next;
  7. cur->next=pre;
  8. pre=cur;
  9. cur=next;
  10. }
  11. return pre;
  12. }

合并两个有序链表

 力扣https://leetcode.cn/problems/merge-two-sorted-lists/description/

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例 1:


输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:

输入:l1 = [], l2 = []
输出:[]
示例 3:

输入:l1 = [], l2 = [0]
输出:[0]
 

提示:

两个链表的节点数目范围是 [0, 50]
-100 <= Node.val <= 100
l1 和 l2 均按 非递减顺序 排列

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/merge-two-sorted-lists
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解:

思路:比较简单,创建一个带头结点的链表,去比较数据的大小尾插到新链表的后面即可。

  1. struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
  2. struct ListNode* cur1=list1;
  3. struct ListNode* cur2=list2;
  4. struct ListNode* guard=(struct ListNode*)malloc(sizeof(struct ListNode));
  5. guard->next=NULL;
  6. struct ListNode* tail=guard;
  7. while(cur1&&cur2)
  8. {
  9. if(cur1->val<cur2->val)
  10. {
  11. tail->next = cur1;
  12. cur1 = cur1->next;
  13. }
  14. else
  15. {
  16. tail->next = cur2;
  17. cur2 = cur2->next;
  18. }
  19. tail = tail->next;
  20. }
  21. if(cur1)
  22. {
  23. tail->next=cur1;
  24. }
  25. if(cur2)
  26. {
  27. tail->next=cur2;
  28. }
  29. struct ListNode* head=guard->next;
  30. free(guard);
  31. return head;
  32. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/991874
推荐阅读
相关标签
  

闽ICP备14008679号