双指针算法以及各种应用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ljt735029684/article/details/84562730

这里双指针指的是在同一个可迭代对象a中使用两个迭代器(下面用i,j)。

反正就要能类似数组这样使用索引i, j来得到对应的值a[i], a[j],然后通过移动i跟j达到目的。下面以数组为例

常见的使用方法有几种:

1. i跟j在数组的两边开始,用来把数组分成两部分

这个我们早遇到过了,我第一次遇见它被用来分成大于最左边的数(基准数)跟小于最左边的数两部分。不过它结合了分治法导致你可能没发现,它就是快速排序。当然快速选择算法中也是同样。记得注意是括号里是取小于等于,因为我们只把右边小于(或大于)的数丢到另一边。

//双指针分组:将数组分成>=temp以及<=temp的两部分 
int quickSort(int a[], int left, int right)
{
	int i = left, j = right;
	int temp = a[left]; 
	while(i < j)
	{
		// 这个可以不需要=,但浪费时间,比起换来换去排序好,不如不动就排序好 
		while(a[j] >= temp && i < j)
			j--;
		// i必须有=,否则才第一个就不会动 
		while(a[i] <= temp && i < j)
			i++;
		
		if(i < j)
		{
            //交换两个数的函数,可以自己编写或者加入algorithm头文件使用
			swap(a[i], a[j]);
			
		}
	}
	swap(a[left], a[i]);
	return i;
}

//分治法 
void quick(int a[], int left, int right)
{
	if(left >= right)
		return;
	int mid = quickSort(a, left, right);
	quick(a, left, mid-1);
	quick(a, mid + 1, right);
	
}

当然,它还可以用来分奇偶数。

void division(int a[], int n)
{  
    int i = 0, j = n - 1;  
        while(true)
        {  
            while(i < j && a[i] % 2 == 1) i++;  
            while(i < j && a[j] % 2 == 0) j--;  
            if(i < j)
            {  
                swap(a[i], a[j]);
            }  
        }  
 }  

2. 快慢指针:求不定长数组(链表)的中间元素(1/3,1/4都一样)

思路:使用两个指针,快指针速度是慢指针的2倍(若1/3则3倍,1/4则4倍),当快指针到达终点时,慢指针到达所求的点

List middle(List)
{
    List qucik = a;
    List slow = a;
    
    while(quick != NULL && quick->next != NULL)
    {
        qucik = quick->next->next;
        slow = slow->next;
    }
    return slow;
}

3. 固定距离指针: 求距离n的点

比如,求链表倒数第n个节点

思路:使用两个指针,一个先走n步,然后一起走

List tailN(List a, int n)
{
    List quick = a;
    List slow = a;
    for(int i = 0; i < n; i++)
    {
        quick = quick->next;
    } 
    while(quick != NULL)
    {
        quick = quick->next;
        slow = slow->next;
    }
    return slow;
}

4.两边微调:有序数组找到两个数的和

比如: 一个递增序列中,找到两个数的和为xx,返回他们的坐标

扫描二维码关注公众号,回复: 4740299 查看本文章

思路:由于是递增的,因此使用两个指针,一个左边i一个右边j,小于xx则让i向右,大于xx则让j向左。

Result sumExist(int a[],int n, int sum)
{
	int i = 0, j = n - 1;
	Result result;
	while(i < j)
	{
		if(a[i] + a[j] < sum)
			i++;
		else if (a[i] + a[j] > sum)
			j--;
		else
			result.add(i);
			result.add(j);
			return result;	
	}
	return NULL;
}

猜你喜欢

转载自blog.csdn.net/ljt735029684/article/details/84562730
今日推荐