当前位置:   article > 正文

画解数据结构刷题之单向链表(翻转函数)_listnode *cur = head;

listnode *cur = head;

链表回文

第一题

  1. bool isPalindrome(struct ListNode* head){
  2. struct ListNode*cur=head;
  3. struct ListNode*vec[100001];
  4. int i=0;
  5. while(cur)
  6. {
  7. vec[i]=cur->val;
  8. cur=cur->next;
  9. i++;
  10. }
  11. int p=0;
  12. int q=i-1;
  13. while(p<q)
  14. {
  15. if(vec[p]!=vec[q])
  16. {
  17. return false;
  18. }
  19. else{
  20. p++;
  21. q--;
  22. }
  23. }
  24. return true;
  25. }

思路:将所有链表数据存入数组,用双指针比较

链表逆序

第一题

  1. int* reversePrint(struct ListNode* head, int* returnSize){
  2. static int ret[10000];
  3. struct ListNode*cur=head;
  4. int i=0;
  5. while(cur)
  6. {
  7. ret[i++]=cur->val;
  8. cur=cur->next;
  9. }
  10. int q=i-1;
  11. for(int j=0;j<i/2;j++)
  12. {
  13. int temp=ret[j];
  14. ret[j]=ret[q];
  15. ret[q]=temp;
  16. q--;
  17. }
  18. *returnSize=i;
  19. return ret;
  20. }

第二题

  1. struct ListNode* reverseList(struct ListNode* head){
  2. struct ListNode*cur=head;
  3. int num=0;
  4. struct ListNode*vec[5001];
  5. if(head==NULL)
  6. {
  7. return NULL;
  8. }
  9. while(cur)
  10. {
  11. vec[num++]=cur;
  12. cur=cur->next;
  13. }
  14. int temp=num-1;
  15. for(int j=num-1;j>0;j--)
  16. {
  17. vec[j]->next=vec[j-1];
  18. }
  19. vec[0]->next=NULL;
  20. return vec[temp];
  21. }

第三题 反转链表2

  1. void reverse(struct ListNode*head)
  2. {
  3. struct ListNode*pre=NULL;
  4. struct ListNode*cur=head;
  5. while(cur!=NULL)
  6. {
  7. struct ListNode*next=cur->next;
  8. cur->next=pre;
  9. pre=cur;
  10. cur=next;
  11. }
  12. }
  13. struct ListNode* reverseBetween(struct ListNode* head, int left, int right){
  14. struct ListNode*dummyhead=malloc(sizeof(struct ListNode));
  15. dummyhead->val=0;
  16. dummyhead->next=head;//虚拟头结点写法,用于头结点可能改变时
  17. struct ListNode*pre=dummyhead;
  18. for(int i=0;i<left-1;i++)//虚拟头结点走left-1步来到left前一个结点
  19. {
  20. pre=pre->next;
  21. }
  22. struct ListNode*rightt=pre;
  23. for(int i=0;i<right-left+1;i++)//来到right结点
  24. {
  25. rightt=rightt->next;
  26. }
  27. struct ListNode*leftnode=pre->next;
  28. struct ListNode*rightnode=rightt->next;//right的后面
  29. pre->next=NULL;
  30. rightt->next=NULL;
  31. reverse(leftnode);
  32. pre->next=rightt;
  33. leftnode->next=rightnode;
  34. return dummyhead->next;
  35. }

注意:

(1)虚拟头结点的写法,dummyhead->next=head

(2)翻转链表函数的简易写法

  1. void reverse (struct Listnode* head)
  2. {
  3. struct Listnode*pre=NULL;
  4. struct Listnode* cur=head;
  5. while(cur)
  6. {
  7. struct Listnode* next=cur->next;//记录cur->next
  8. cur->next=pre;
  9. pre=cur;
  10. cur=next;
  11. }

(3)如何获得链表中特定结点

for循环,记录步数

(4)用reverse函数后,之前记录的结点仍不变,只是后继结点改变而已,因此reverse后直接接上即可

第四题

两数相加2

  1. struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
  2. struct ListNode*cur=l1;
  3. struct ListNode*vec1[101];
  4. struct ListNode*ret[101];
  5. int len1=0;
  6. int m1=0;
  7. while(cur)
  8. {
  9. vec1[m1++]=cur;
  10. len1++;
  11. cur=cur->next;
  12. }
  13. struct ListNode*cur2=l2;
  14. struct ListNode*vec2[101];
  15. int len2=0;
  16. int m2=0;
  17. while(cur2)
  18. {
  19. vec2[m2++]=cur2;
  20. len2++;
  21. cur2=cur2->next;
  22. }
  23. if(len1>=len2)
  24. {
  25. int temp=len1-len2;
  26. int q1=len1-1;
  27. int q2=len2-1;
  28. int add=0;
  29. for(int i=q1;i>=temp;i--)
  30. {
  31. int temp2=vec1[i]->val+vec2[q2--]->val+add;
  32. if(temp2>=10)
  33. {
  34. add=1;
  35. temp2=temp2-10;
  36. }
  37. else{
  38. add=0;
  39. }
  40. vec1[i]->val=temp2;
  41. }
  42. return vec1[0];
  43. }
  44. else{
  45. int temp=len2-len1;
  46. int q1=len1-1;
  47. int q2=len2-1;
  48. int add=0;
  49. for(int i=q2;i>=temp;i--)
  50. {
  51. int temp3=vec2[q2]->val+vec1[q1--]->val+add;
  52. if(temp3>=10)
  53. {
  54. add=1;
  55. temp3=temp3-10;
  56. }
  57. else{
  58. add=0;
  59. }
  60. vec2[i]->val=temp3;
  61. }
  62. return vec2[0];
  63. }
  64. return 0;
  65. }

实在看不懂题解里的栈,我是废物

下为翻转函数头尾指针版,返回的是翻转后的头

  1. struct ListNode*reverse(struct ListNode*head,struct ListNode*tail){
  2. if(head->next==tail)
  3. return head;
  4. struct ListNode*p1=reverse(head->next,tail);
  5. head->next->next=head;
  6. head->next=NULL;
  7. return p1;
  8. }

链表遍历

第一题

  1. struct ListNode* partition(struct ListNode* head, int x){
  2. struct ListNode* small=malloc(sizeof(struct ListNode));
  3. struct ListNode*p1=small;
  4. struct ListNode*smallhead=small;
  5. struct ListNode* big=malloc(sizeof(struct ListNode));
  6. struct ListNode*p2=big;//因为是新链表所以要malloc
  7. struct ListNode*largehead=big;
  8. struct ListNode*cur=head;
  9. while(cur)
  10. {
  11. if(cur->val<x)
  12. {
  13. p1->next=cur;
  14. cur=cur->next;
  15. p1=p1->next;
  16. }
  17. else
  18. {
  19. p2->next=cur;
  20. cur=cur->next;
  21. p2=p2->next;
  22. }
  23. }
  24. p2->next=NULL;
  25. p1->next=largehead->next;
  26. return smallhead->next;
  27. }

维护两个链表,一个小于x,一个大于等于x

第二题

  1. struct ListNode* swapNodes(struct ListNode* head, int k){
  2. struct ListNode *tar1,*tar2;//目标结点
  3. int num=0;
  4. struct ListNode *fast;
  5. fast=head;
  6. tar2=head;
  7. while(--k)
  8. {
  9. fast=fast->next;
  10. }
  11. tar1=fast;//此时tar1为第k个结点
  12. while(fast->next)
  13. {
  14. fast=fast->next;
  15. tar2=tar2->next;//此时tar2为倒数第k个结点
  16. }
  17. num=tar1->val;
  18. tar1->val = tar2->val;
  19. tar2->val = num;
  20. return head;
  21. }

一次遍历找到第k个和倒数第k个,先遍历k-1次,找到第k个,然后让fast继续遍历len-(k-1)次,tar2同时从头开始遍历len-(k-1)次

链表结点删除

第一题

  1. struct ListNode* deleteNode(struct ListNode* head, int val){
  2. struct ListNode*dummyhead=malloc(sizeof(struct ListNode));
  3. dummyhead->next=head;
  4. dummyhead->val=-1;//虚拟头指针
  5. struct ListNode*cur=head;
  6. if (cur->val == val) {
  7. return cur->next;
  8. }
  9. while(cur)
  10. {
  11. if(cur->next->val==val)
  12. {
  13. cur->next=cur->next->next;
  14. break;
  15. }
  16. cur=cur->next;
  17. }
  18. return dummyhead->next;
  19. }

第二题

  1. void deleteNode(struct ListNode* node) {
  2. node->val=node->next->val;
  3. node->next=node->next->next;
  4. }

 将next赋值给node,把next的next赋值给node的next

第三题

  1. struct ListNode* removeZeroSumSublists(struct ListNode* head){
  2. struct ListNode*pre=malloc(sizeof(struct ListNode));
  3. pre->next=head;
  4. pre->val=0;
  5. struct ListNode*left=pre;
  6. int sum;
  7. while(left)
  8. {
  9. sum=0;
  10. struct ListNode*right=left->next;
  11. while(right)
  12. {
  13. sum+=right->val;
  14. if(sum==0)
  15. {
  16. left->next=right->next;
  17. }
  18. right=right->next;
  19. }
  20. left=left->next;
  21. }
  22. return pre->next;
  23. }

思路:维护n方的前缀和,注意第一次的left从头结点的前继结点开始算,因为right=left->next,让right从头结点开始算

链表索引

第一题

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

找中间结点,快指针一次走两步,慢指针一次走一步,当快指针走到表尾或快要走到表尾时,慢指针就会达到中间结点

第二题

  1. int* nextLargerNodes(struct ListNode* head, int* returnSize){
  2. struct ListNode*left=head;
  3. int *ret = (int*)malloc(sizeof(int)*10001);
  4. memset(ret,0,sizeof(int)*10001);
  5. int i=0;
  6. while(left)
  7. {
  8. struct ListNode*right=left->next;
  9. while(right)
  10. {
  11. if(right->val>left->val)
  12. {
  13. ret[i]=right->val;
  14. break;
  15. }
  16. right=right->next;
  17. ret[i]=0;
  18. }
  19. i++;
  20. left=left->next;
  21. }
  22. *returnSize=i;
  23. return ret;
  24. }

链表交换

第一题

 

  1. struct ListNode* swapPairs(struct ListNode* head) {
  2. struct ListNode dummyHead;
  3. dummyHead.next = head;
  4. struct ListNode* temp = &dummyHead;
  5. while (temp->next != NULL && temp->next->next != NULL) {
  6. struct ListNode* node1 = temp->next;
  7. struct ListNode* node2 = temp->next->next;
  8. temp->next = node2;
  9. node1->next = node2->next;
  10. node2->next = node1;
  11. temp = node1;
  12. }
  13. return dummyHead.next;
  14. }

思路:当需要分组作业时,可以不用划分特定组,可以像这道题一样,规定一个temp做检测变量,每次变换temp后的两个结点,最后把第二个结点赋值给temp即可

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

闽ICP备14008679号