精选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; 
 }





相关推荐
xin_nai2 小时前
LeetCode热题100(Java)(4)子串
java·算法·leetcode
一只数据集2 小时前
机器学习多领域综合数据集分析-包含基因表达时间序列分类回归数据-适用于算法训练模型评估科研应用
人工智能·算法·数据分析
c++之路2 小时前
C++ 命名空间(Namespace)
开发语言·c++·算法
jiang_bluetooth3 小时前
奈奎斯特第一准则理解和WIFI OFDM的关联
算法
DuHz10 小时前
论文精读:大语言模型 (Large Language Models, LLM) —— 一项调查
论文阅读·人工智能·深度学习·算法·机器学习·计算机视觉·语言模型
加农炮手Jinx10 小时前
LeetCode 72. Edit Distance 题解
算法·leetcode·力扣
借雨醉东风10 小时前
程序分享--常见算法/编程面试题:旋转矩阵
c++·线性代数·算法·面试·职场和发展·矩阵
_深海凉_10 小时前
LeetCode热题100-打家劫舍
算法·leetcode·职场和发展
jghhh0111 小时前
使用 MATLAB 实现支持向量回归 (SVR) 预测未来数据
算法·matlab