1.旋转数组
将数组中的元素向右轮转
k个位置
方法1:memcpy:
-
创建新数组
-
将对应位置上的数据memcpy上去
-
将整个新数组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:逆置:

-
实现给定地址的逆置函数
-
逆置整个数组
-
根据题目要求逆置对应的位置
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包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。
-
-
具有交换律
-
两个相同数字异或得到0
-
0和 数字n 异或得到 n
-
-
将整个数组与对应的本该有的全部数字异或之后,就可以得到消失的数字
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
-
让快指针先向后走k步,
-
然后让快慢指针都向后走
-
等快指针走到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.判断链表是不是回文链表

-
找到中间节点------实现找到中间节点的函数
-
将中间节点后面的链表反转,并且返回整个链表的尾节点,作为后半链表的头节点------实现函数
-
双指针,一个从头向中间,一个从尾向中间,
-
判断每一个对称的数是否相等,
-
不想等就不是回文链表
-
所有对称数字都相等就是回文链表
-
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.找到两个链表的公共节点

-
求出两个链表的长度cnta,cntb
-
将长的设为长链表longlist,短的设为短链表shortlist
-
长链表的指针先向后走,走到二者对齐的位置(图中的a1和b2)
-
两个指针同步向后走,直到两指针到同一节点
-
返回同一节点
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,是随机指向的
我们需要复制一份,然后返回复制出来的链表的头节点

-
在每一个节点后面新创建一个节点,相当于插入操作
-
改变新节点的random的指向
-
将新节点们 独立开来------改变next的指向
-
返回新节点们 的头节点


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