一.快排
void QuickSort(int* nums,int left,int right){
if(left>right)
return;
int i=left;
int j =right;
int key=nums[left];
int temp;
while(i<j){
while(i<j&&nums[j]>=key)
j--;
while(i<j&&nums[i]<=key)
i++;
if(i<j){
temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
}
nums[left]=nums[i];
nums[i]=key;
QuickSort(nums,left,i-1);
QuickSort(nums,i+1,right);
}
二.二分查找
int mid;
while(left<=right){//区间左闭右闭,即left=right的话也是可以执行的
mid=(left+right)/2;
//由于区间是左闭右闭的,下面的if语句判断的是mid的值,判断后如果mid不等于target
//我们就应该把这个值排除出区间,因此right应该是mid+1,left应该是mid-1
if(nums[mid]>target)
right=mid-1;
else if(nums[mid]<target)
left=mid+1;
else
return mid;
}
三.双指针法
1.用于在单调遍历中有选择性地保留数组元素
int i=0;
int k=0;
while(i<length){
//由于这里是顺序赋值,i和k都是单调增加,所以可以把k下标想象成一个新数组的下标
//如果nums[i]元素符合保留的要求,再赋进k下标
if(nums[i]是要保留的元素)
nums[k++]=nums[i];
i++;//无论是否符合要求,i下标都递增
}
length=k;
2.用于找到链表倒数第k个元素
ListNode*L=(ListNode*)malloc(sizeof(ListNode));
L->next=head//如果头结点带数据,先创建一个虚空头结点指向原头结点
ListNode* pre=L;
ListNode* cur=L
//先把cur指针向后移动k位,再将pre和cur一起移动,直至cur指向最后一个结点
//此时pre指向倒数第k个元素的上一个结点
//(倒数第k位的意思是该元素加上之后所有元素共有k个元素
//而因为cur初始化时刚开始等于pre,再向后移动k位,所以pre到cur(包括pre和cur)共有k+1个元素
//因此pre指向倒数第k个元素的上一个结点)
while(n--){
cur=cur->next;
}
while(cur->next!=NULL){
cur=cur->next;
pre=pre->next;
}
ListNode* k=pre->next;
3.通过快慢两个指针来判定是否有环
ListNode* fast=head;
ListNode* Node=head;
//快指针每次走两步,慢指针每次走一步,可以理解成一个相对运动过程
//即慢指针相对静止,则快指针相对慢指针每次走一步,因此如果有环
//快指针每次走这一步经过若干轮一定能追到静止的慢指针
while(fast->next!=NULL&&fast->next->next!=NULL){
fast=fast->next->next;
slow=slow->next;
if(fast==slow){
return right;
}
}
return false;
接上:
如果要找到环的入口结点的话:
ListNode* temp=head;
while(temp!=slow){
temp=temp->next;
slow-slow->next;
}
return temp;
思路源自代码随想录:https://www.bilibili.com/video/BV1if4y1d7ob/?vd_source=a0e37a7389fd27bbf96cfc922f12c61d