数组、链表常用思路即模板:快排,二分查找,双指针法||C语言


一.快排

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值