精选5大高频链表与数组算法详解:从旋转数组到链表公共节点,LeetCode实战代码+图解全解析

1.旋转数组

将数组中的元素向右轮转 k 个位置

方法1:memcpy:

  1. 创建新数组

  2. 将对应位置上的数据memcpy上去

  3. 将整个新数组memcpy到源数组中

cpp 复制代码
 void rotate(int* nums, int numsSize, int k) 
 {
     k%=numsSize;
     int *tmp=(int*)malloc(numsSize*sizeof(int));
     memcpy(tmp,nums+numsSize-k,k*sizeof(int));
     memcpy(tmp+k,nums,(numsSize-k)*sizeof(int));
 ​
     memcpy(nums,tmp,numsSize*sizeof(int));
 }
 


方法2:逆置:

  1. 实现给定地址的逆置函数

  2. 逆置整个数组

  3. 根据题目要求逆置对应的位置

cpp 复制代码
 //逆置
 void reverse(int* begin,int *end)
 {
     while(begin<end)
     {
             int tmp=*begin;
             *begin=*end;
             *end=tmp;
 ​
             begin++;
             end--;
     }
 }
 ​
 void rotate(int* nums, int numsSize, int k) 
 {
     k%=numsSize;
     reverse(nums,nums+numsSize-1);
     reverse(nums,nums+k-1);
     reverse(nums+k,nums+numsSize-1);
     
 }





2.消失的数字

数组nums包含从0n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。

  1. 异或^

    1. 具有交换律

    2. 两个相同数字异或得到0

    3. 0和 数字n 异或得到 n

  2. 将整个数组与对应的本该有的全部数字异或之后,就可以得到消失的数字

cpp 复制代码
 int missingNumber(int* nums, int numsSize) 
 { 
     int ret=0;
     for(int i=0;i<numsSize;i++)
     {
             ret^=nums[i];
     }
     for(int i=0;i<=numsSize;i++)
     {
         ret^=i;
     }
     return ret;
 }





3.找到倒数第k个节点

返回链表倒数第k个节点的val

  1. 让快指针先向后走k步,

  2. 然后让快慢指针都向后走

  3. 等快指针走到NULL,慢指针 就在倒数第k个节点

cpp 复制代码
 /**
  * Definition for singly-linked list.
  * struct ListNode {
  *     int val;
  *     struct ListNode *next;
  * };
  */
 ​
  ///双指针法:
 int kthToLast(struct ListNode* head, int k) {
     struct ListNode* fast=head;
     struct ListNode* slow=head; 
     while(k--)
     {
         fast=fast->next;
     }
     while(fast&&slow)
     {
         fast=fast->next;
         slow=slow->next; 
     }
 ​
     return slow->val;
 ​
 }





4.判断链表是不是回文链表

  1. 找到中间节点------实现找到中间节点的函数

  2. 将中间节点后面的链表反转,并且返回整个链表的尾节点,作为后半链表的头节点------实现函数

  3. 双指针,一个从头向中间,一个从尾向中间,

  4. 判断每一个对称的数是否相等,

    1. 不想等就不是回文链表

    2. 所有对称数字都相等就是回文链表

复制代码
 
cpp 复制代码
/*
 struct ListNode {
     int val;
     struct ListNode *next;
     ListNode(int x) : val(x), next(NULL) {}
 };*/
 class PalindromeList {
 public:
     ListNode* getmid(ListNode* phead)
     {
         ListNode* fast=phead;
         ListNode* slow=phead;
 ​
         while(fast&&fast->next)
         {
             fast=fast->next->next;
             slow=slow->next;
         }
 ​
         return slow;
     }
     
 ​
     ListNode* getantihead(ListNode* mid)
     {
         ListNode* next=mid->next;
         ListNode* pcur=mid;
 ​
         ListNode*pre=NULL;
         while(pcur )
         {    
             pcur->next=pre;
             pre=pcur;
             pcur=next;
             if(pcur!=NULL)
                 next=pcur->next;
         }
 ​
         return pre;
     }
     
     
     
     bool chkPalindrome(ListNode* A) {
         // write code here
 ​
         ListNode*mid=getmid(A);
         ListNode*antihead=getantihead(mid);
 ​
         ListNode*phead=A;
         while(phead&&antihead)
         {
             if(phead->val !=antihead->val)
                 return false;
 ​
             phead=phead->next;
             antihead=antihead->next;
         }
         return true; 
     }
 };





5.找到两个链表的公共节点

  1. 求出两个链表的长度cnta,cntb

  2. 将长的设为长链表longlist,短的设为短链表shortlist

  3. 长链表的指针先向后走,走到二者对齐的位置(图中的a1和b2)

  4. 两个指针同步向后走,直到两指针到同一节点

  5. 返回同一节点

复制代码
 
cpp 复制代码
/**
  * Definition for singly-linked list.
  * struct ListNode {
  *     int val;
  *     struct ListNode *next;
  * };
  */
 struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
 ​
     struct ListNode*pcur=headA;
     int cnta=0;
     while(pcur)
     {
         cnta++;
         pcur=pcur->next;
     }
 ​
      pcur=headB;
     int cntb=0;
     while(pcur)
     {
         cntb++;
         pcur=pcur->next;
     }
 ​
      struct ListNode *longlist=headA;
       struct ListNode *shortlist=headB;
 ​
     if(cnta<cntb)
     {
 ​
         longlist=headB;
         shortlist=headA;        
     }
 ​
     int gap=abs(cnta-cntb);
     while(gap--)
     {
         longlist =longlist->next;
     }
 ​
     while(longlist !=shortlist )
     {
         if(longlist->next&&shortlist->next)
         {
             longlist=longlist->next;
             shortlist=shortlist->next;
         }
         else
             return NULL;
     }
     return longlist;
     
      
     
 }





6.链表的复制------深拷贝

这个链表中出来next还有一个random,是随机指向的

我们需要复制一份,然后返回复制出来的链表的头节点

  1. 在每一个节点后面新创建一个节点,相当于插入操作

  2. 改变新节点的random的指向

  3. 将新节点们 独立开来------改变next的指向

  4. 返回新节点们 的头节点

复制代码
 
cpp 复制代码
/**
  * Definition for a Node.
  * struct Node {
  *     int val;
  *     struct Node *next;
  *     struct Node *random;
  * };
  */
 ​
 struct Node* copyRandomList(struct Node* head) 
 {
 ​
     if(head==NULL)
         return head;
     struct Node* pcur=head;
 ​
     while(pcur)
     {
         struct Node* next=pcur->next;
 ​
         struct Node* newnode=(struct Node*)malloc(sizeof(struct Node)) ;
         newnode->val=pcur->val;
         newnode->next=pcur->next; 
         newnode->random=NULL; 
         pcur->next=newnode;
 ​
         pcur=next; 
     }
 ​
     pcur=head ;
     while(pcur)
     {
         if(pcur->random==NULL)
         {
             pcur->next->random=NULL;
         }
         else
         { 
              pcur->next->random=pcur->random->next;
         }
 ​
         pcur=pcur->next->next;
     }
 ​
     pcur=head->next;
     while(pcur)
     {
         if(pcur->next==NULL)
             break;
         else
         {
             pcur->next= pcur->next->next;
             pcur=pcur->next;
         }
     }
 ​
     return head->next; 
 }





相关推荐
小雨下雨的雨6 小时前
井字棋AI机器人实现详解 - Minimax算法实战-鸿蒙PC Electron框架完成
前端·人工智能·算法·华为·electron·鸿蒙
xieliyu.8 小时前
Java算法精讲:双指针(三)
java·开发语言·算法
一条小锦吕*8 小时前
基于Spring Boot + 数据可视化 + 协同过滤算法的推荐系统设计与实现(源码+论文+部署全讲解)
spring boot·算法·信息可视化
如竟没有火炬10 小时前
最大矩阵——单调栈
数据结构·python·线性代数·算法·leetcode·矩阵
8Qi811 小时前
LeetCode 1143 & 718:最长公共子序列 / 最长重复子数组
算法·leetcode·职场和发展·动态规划
绿算技术11 小时前
万卡推理集群存储选型分析:从核心架构到应用视角
大数据·科技·算法·架构
想吃火锅100512 小时前
【leetcode】1.两数之和js版
javascript·算法·leetcode
net3m3313 小时前
一阶软件低通滤波器算法
人工智能·算法
水木流年追梦13 小时前
大模型入门-大模型优化方法12-YaRN 长文本外推技术
人工智能·分布式·算法·正则表达式·prompt