当前位置:   article > 正文

leetcode刷题——单链表_单链表 leetcode

单链表 leetcode

目录

练习题1移除链表元素

带哨兵头

练习题2合并两个有序链表  ​编辑

练习题3反转链表 

习题4 链表的中间节点 

习题5 倒数第K个节点 

练习题1移除链表元素

点这里跳转做题

 要考虑的情况

 

如果只有一个节点,且这个节点要删除,则返回NULL 

  1. struct ListNode* removeElements(struct ListNode* head, int val){
  2. while(head != NULL && head->val == val){
  3. head = head->next;
  4. }
  5. struct ListNode* fast = head;
  6. struct ListNode* slow =head;
  7. struct ListNode* slow1 =head;
  8. if (head ==NULL)
  9. return NULL;//如果头节点为空,则直接返回
  10. while (fast!= NULL)
  11. {
  12. while (fast->val!=val)
  13. {
  14. slow = fast;
  15. if (slow->next == NULL)
  16. return head;//如果遍历完整个链表,fast为NULL,都没找到val,则直接返回
  17. fast = fast->next;
  18. }
  19. if (fast->val == val)
  20. {
  21. slow->next = fast->next;
  22. fast = fast->next;//跨过要删除的节点
  23. }
  24. }
  25. if (slow1->val==val)//如果只有一个节点,且这个节点要删除,则返回空
  26. return NULL;
  27. return head;
  28. }

  1. struct ListNode* removeElements(struct ListNode* head, int val){
  2. struct ListNode* cur=head;
  3. struct ListNode* prve=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. prve->next=cur->next;
  17. free(cur);
  18. cur=prve->next;
  19. }
  20. }
  21. else
  22. { prve=cur;
  23. cur=cur->next;
  24. }
  25. }
  26. return head;
  27. }

还可以把 非valu的节点,插到新链表

  1. struct ListNode* removeElements(struct ListNode* head, int val){
  2. struct ListNode* cur=head;
  3. struct ListNode* tail=NULL;
  4. struct ListNode* newhead=NULL;
  5. while(cur)
  6. {
  7. if(cur->val!=val)
  8. {
  9. if(tail==NULL)
  10. {
  11. tail=newhead=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. tail->next=NULL;
  29. return newhead;
  30. }

带哨兵头

 

head不存储有效数据

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

带哨兵位的头节点,传参的时候不需要传二级指针

替代之前的二级指针:

1.返回新链表头

2.设计为带哨兵位

单链表:

1.实际运用中很少带头

2.OJ题基本不带头

练习题2合并两个有序链表  

  1. struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
  2. struct ListNode*newhead=(struct ListNode*)malloc(sizeof(struct ListNode));
  3. struct ListNode*tail=newhead;
  4. while(list1!=NULL&&list2!=NULL)
  5. {
  6. if(list1->val>list2->val)
  7. {
  8. newhead->next=list2;//newhead与第小的数链接
  9. list2=list2->next;//遍历下一个数
  10. }
  11. else
  12. {
  13. newhead->next=list1;
  14. list1=list1->next;
  15. }
  16. newhead=newhead->next;//newhead往下走,要存下一个数
  17. }
  18. while(list1!=NULL)
  19. {
  20. newhead->next=list1;
  21. list1=list1->next;
  22. newhead=newhead->next;
  23. }
  24. while(list2!=NULL)
  25. {
  26. newhead->next=list2;
  27. list2=list2->next;
  28. newhead=newhead->next;
  29. }
  30. newhead->next=NULL;
  31. return tail->next;
  32. }

练习题3反转链表 

点这里跳转

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

 方法二:反转链表

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

习题4 链表的中间节点 

点这里跳转

  1. struct ListNode* middleNode(struct ListNode* head){
  2. struct ListNode*fast,* slow;
  3. fast=slow=head;
  4. while(fast&&fast->next)
  5. {
  6. slow=slow->next;
  7. fast=fast->next->next;
  8. }
  9. return slow;
  10. }

 采用快慢指针:快指针一次走俩步,慢指针走一步

习题5 倒数第K个节点 

采用快慢指针法

方法一:fast先走k步,然后slow和fast一块一步一步走,等fast位空,则停止前进,slow所在位置就是倒数第k个

这里k=4,则slow要等于倒数第四个

 

fast为空,找到了

方法二:fast先走k-1补,然后slow和fast一起一步一步走,等fast->next=NULL,则找到了 

  1. struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
  2. struct ListNode* fast=pListHead;
  3. struct ListNode *slow=pListHead;
  4. if(pListHead==NULL)
  5. return NULL;
  6. while(k--)
  7. {
  8. if(fast)
  9. fast=fast->next;
  10. else
  11. return NULL;
  12. }
  13. while(fast)
  14. {
  15. slow=slow->next;
  16. fast=fast->next;
  17. }
  18. return slow;
  19. }

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

闽ICP备14008679号