当前位置:   article > 正文

【链表】算法题(一) ----- 力扣 / 牛客

【链表】算法题(一) ----- 力扣 / 牛客

一、移除链表元素

        移除链表中值为val的元素,并返回新的头节点

思路:

题目上这样说,我们就可以创建一个新的链表,将值不为val的节点,尾插到新的链表当中,最后返回新链表的头节点。

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

        当然,这个题还有其他思路。

二、反转链表

        将链表反转,并返回反转后的链表的头节点

思路:

        创建三个指针变量,l1,l2,l3(指针初始指向如下图),遍历链表,先让l3=l2->next;再将l2的next指针指向l2;再l1指向l2,l2指向l3(l2下一个节点);直到遍历结束,结束条件为(l2等于NULL)此时l1指向的就是反转后的链表的头节点。

根据题目给的示例来分析

遍历数组,循环进行一次

l2不等于NULL循环继续

l2不等于NULL循环继续

l2不等于NULL循环继续

l2仍然不等于NULL,循环继续

到这里,l2已经遍历到了NULL,循环结束,此时l1指向的就是反转后链表的头节点,直接返回即可。

  1. typedef struct ListNode ListNode;
  2. struct ListNode* reverseList(struct ListNode* head) {
  3. ListNode* l1,*l2,*l3;
  4. l1=NULL;
  5. l2=head;
  6. while(l2)
  7. {
  8. l3=l2->next;
  9. l2->next=l1;
  10. l1=l2;
  11. l2=l3;
  12. }
  13. return l1;
  14. }

三、链表的中间节点

        看到这个题,本人一开始的想法是:遍历一遍链表,记录链表的节点个数,然后再遍历一次链表,寻找链表的中间节点;这样实现非常麻烦,现在使用一种新的方法来解决这个问题

思路:快慢指针

        定义两个快慢指针,fast和slow刚开始都指向链表的头节点,fast每次向前走两个节点,而slow指针每次向前走一个节点;最后当fast指针或者fast的next指针为NULL遍历结束;此时slow指向的就是链表的中间节点。

根据题所给的示例分析:
        链表个数为奇数

fast=fsat->next->next;

slow=slow->next;

           

遍历到这里,fast的next指针为空,循环结束;此时slow指向的就是链表的中间节点。

        链表的节点数为偶数

fast=fsat->next->next;

slow=slow->next;

循环到这里,fast为空,循环结束,此时slow指向的节点就是链表的中间节点。

  1. typedef struct ListNode ListNode;
  2. struct ListNode* middleNode(struct ListNode* head) {
  3. if(head==NULL)
  4. {
  5. return NULL;
  6. }
  7. ListNode* fast=head;
  8. ListNode* slow=head;
  9. while(fast&&fast->next)
  10. {
  11. fast=fast->next->next;
  12. slow=slow->next;
  13. }
  14. return slow;
  15. }

四、合并两个有序链表

        合并两个有序链表,这里创建一个新的链表,将两个链表中较小小的数据依次尾插到新链表中,最后返回新链表的头节点即可。

        注意:这里需要注意,初始的两个链表可能为空,这里需要进判断,如果list1为空,就返回list1;如果list2为空,就返回list1。

根据题目示例分析

        比较l1和l2指向的节点的值大小,l1->val=l2->val(l1的不小于l2的),将l2指向节点尾插到新链表

        此时,l1->val < l2->val,将l1指向的节点尾插到新链表

        此时,l1->val < l2->val,将l1指向的节点尾插到新链表

比较l1和l2指向的节点的值大小,l2->val < l1->val,将l2指向节点尾插到新链表

        比较l1和l2指向的节点的值大小,l1->val=l2->val(l1的不小于l2的),将l2指向节点尾插到新链表

        l2为空,循环结束,这里l1的节点还没全部插到新链表中,这里直接 ptail->next=l1;即可。

注:这里使用动态内存来给newhead开辟空间,记得将其释放掉,养成好习惯。

  1. typedef struct ListNode ListNode;
  2. struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
  3. if(list1==NULL)
  4. {
  5. return list2;
  6. }
  7. if(list2==NULL)
  8. {
  9. return list1;
  10. }
  11. ListNode* l1=list1;
  12. ListNode* l2=list2;
  13. ListNode* newhead=(ListNode*)malloc(sizeof(ListNode));
  14. ListNode* ptail=newhead;
  15. while(l1 && l2)
  16. {
  17. if(l1->val<l2->val)
  18. {
  19. ptail->next=l1;
  20. l1=l1->next;
  21. }
  22. else
  23. {
  24. ptail->next=l2;
  25. l2=l2->next;
  26. }
  27. ptail=ptail->next;
  28. }
  29. if(l1)
  30. {
  31. ptail->next=l1;
  32. }
  33. if(l2)
  34. {
  35. ptail->next=l2;
  36. }
  37. ListNode* ret=newhead->next;
  38. free(newhead);
  39. newhead=NULL;
  40. return ret;
  41. }

五、链表分割

将链表小于x的节点排在其余节点之前,不能改变原来顺序,最后返回排序好的链表的头指针。

思路:

        创建两个链表,一个链表l1,存放值小于val的节点;另一个链表l2,存放值大于等于val的节点。最后将两个链表连接起来,返回l1链表的头节点即可。

这里需要注意:再l2链表的结尾,要将尾节点的next指针置为NULL;

  1. #include <cstddef>
  2. class Partition {
  3. public:
  4. ListNode* partition(ListNode* pHead, int x) {
  5. // write code here
  6. ListNode* list1,*l1;
  7. l1=list1=(ListNode*)malloc(sizeof(ListNode));
  8. ListNode* list2, *l2;
  9. l2=list2=(ListNode*)malloc(sizeof(ListNode));
  10. ListNode* ptail=pHead;
  11. while(ptail)
  12. {
  13. if(ptail->val<x){
  14. //尾插到l1里
  15. l1->next=ptail;
  16. l1=l1->next;
  17. }
  18. else{
  19. l2->next=ptail;
  20. l2=l2->next;
  21. }
  22. ptail=ptail->next;
  23. }
  24. l2->next=NULL;
  25. l1->next=list2->next;
  26. ListNode* ret=list1->next;
  27. free(list1);
  28. free(list2);
  29. list1=list2=NULL;
  30. return ret;
  31. }
  32. };

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

闽ICP备14008679号