Day 7_2 two pointers


Content writing is very simple, suitable for fast recall of these algorithms in the case learned, did not learn it, you can understand the specific Baidu

1.two Pointers

Examples: Given an increasing sequence of positive integers a and M, find a sequence number of two different positions and b, such that their sum is exactly equal to M, the output of all programs that satisfy the condition
solution

  1. Use double loop to enumerate, but if a long sequence of high complexity
void foreach(int a[],int M){
	int n = sizeof(a)/sizeof(int); 
	for(int i=0;i<n;i++){
		for(int j=i+1;j<n;j++){
			if(a[i]+a[j] == M)
				printf("%d %d\n",a[i],a[j]); 
		}
	}
}
  1. Above optimize a program
    as a sequence of incremented to find a [i] + a [j ] = M, the i, j + 1 as well as the subsequent i + 1, j later, the remaining two numbers together affirm greater than M, no need to continue to traverse down
    the initial order i = 0, j = n- 1, i gradually to the right, j to the left
    1) If a [i] + a [j ] = M, a [i + 1] + a [j]> M, a [i] + a [j-1] <M, but a [i + 1] + a [j-1] M relation is unknown, so the answer is only possible [i + 1, j-1] interval is generated, so that i = i + 1, j = j-1 continue
    2) If a [i] + a [j ]> M, a [i + 1] + a [j]> M, but a [i] + a [j -1] and the M relation is unknown, so the answer is only possible interval generated [i, j-1], so that j = j-1 continued
    3) If a [i] + a [j] <M, a [ i] + a [j-1] <M, but a [i + 1] + a [j] M relation is unknown, so the answer is only possible in the [i + 1, j] interval generating, so that i = i + 1 continue
    repeating the above three steps, knowni>=jSet up
void foreach2(int a[],int M){
	int n = sizeof(a)/sizeof(int); 
	int i=0,j = n-1;
	while(i<j){
		if(a[i]+a[j] == M){
			printf("%d %d\n",a[i],a[j]);
			i++;
			j--;
		}else if(a[i]+a[j] < M){
			i++;
		}else{
			j--;
		}		 
	}
}

2. merge sort

2-way merge sort: sequence number pair off into n / 2 groups, groups within a single sort, two groups and the two groups were combined to obtain n / 4 groups, groups within a single sort order analogy. Until only one group

Merge function

const int maxn = 100; 
//将数组A的[L1,R1]与[L2,R2]的区间合并为有序区间 
void merge(int A[],int L1,int R1,int L2,int R2){
	int i = L1,j = L2;
	int temp[maxn],index = 0;
	while(i <= R1 && j<= R2){
		if(A[i]<=A[j]){
			temp[index++] = A[i++];
		}else{
			temp[index++] = A[j++];
		}
	} 
	while(i <= R1)	temp[index++] = A[i++];
	while(j <= R2)	temp[index++] = A[j++];
	for(int i = 0;i<index;i++){
		A[L1 + i] = temp[i];
	}
}

1. recursive

//将array数组当前区间[left,right]进行归并排序 
void mergeSort(int A[],int left,int right){
	if(left < right){
		int mid = (left+right)/2;
		mergeSort(A,left,mid);
		mergeSort(A,mid+1,right);
		merge(A,left,mid,mid+1,right);
	}
}

2. Non-recursive
The number of elements within each group are multiples of 2, then a step setting step, the initial value is 2, then each step elements of the array as a group, the internal sorting, by step 2, before continuing the step of until step / 2 more than the number of elements n

void mergeSort(int A[],int left,int right){
	//step为组内元素个数,step/2 为左区间元素个数,等号可以不取 
	for(int step = 2;step/2<=n;step *=2){
		//每step个元素一组,组内前step/2个元素进行合并 
		for(int i = 1;i<=n;i+=step){	//对每一组 
			int mid = i + step/2 - 1;	//左子区间元素个数为step/2 
			if(mid + 1 <= n){			//右子区间存在元素则合并 
				merge(A,i,mid,mid+1,min(i + step - 1,n));
			}  
		}
	} 
}

3. Quick Sort

Be sorted array A, A, looking in asentinel(Try randomly determined Sentinel), for example, A [1], to adjust the array sequence, so that the number of A [1] on the left are smaller than A [1], the right side are larger than the A [1], and A [1] on the left and right the sequence of each has to find a sentry, repeat

  1. First A [1] stored in the temporary variable temp inside, and to make two subscripts left = 1, right = n, inclusive point sequence
  2. As long as A [left] <temp, continue to increment the left to the right, when a certain time A [left]> = temp, the element A [left] moved to the right point to the elements A [right] at
  3. As long as A [right]> temp, the increment continues right to the left, when a time A [lright]> = temp, the element A [right] moved to the left pointing element A [left] at
  4. Repeat 2, 3, know left to meet with right, the temp into the place of encounter
#include<stdio.h>
int Partition(int A[],int left,int right){
	int temp = A[left];
	while(left < right){
		while(left < right && A[right] > temp)	right--;
		A[left] = A[right];
		while(left < right && A[left] <= temp)	left++;
		A[right] = A[left];
	}
	A[left] = temp;
	return left;
} 
//快速排序,left,right是序列首尾的下标
void quickSort(int A[],int left,int right){
	if(left < right){
		int pos = Partition(A,left,right);
		quickSort(A,left,pos-1);
		quickSort(A,pos+1,right);
	} 
} 
int main(){
	int a[] = {1,5,4,8,3,6,7,9,10,25,41,62,26,35};
	quickSort(a,0,13);
	for(int i = 0;i<14;i++)
		printf("%d ",a[i]);
	return 0;
}

When random sequence comparison, the highest efficiency, close to the orderly sequence, to reach the worst complexity, and therefore selected randomly chosen Sentinel

1) A method for generating random numbers

Note Adding two header files, and initialize the random seed

#include<stdio.h>
#include<stdlib.h>
#include <time.h> 
int main(){
	srand((unsigned)time(NULL)); //初始化随机种子 
	for(int i = 0;i<10;i++)
		printf("%d ",rand());	 //生成[0,32767]之间的数,常数RAND_MAX = 32767  
	printf("\n\n");
	//rand()%a	生成[0,a-1]之间的数
	//rand()%(b-a+1) + a	生成[a,b]之间的数
	for(int i = 0;i<10;i++)
		printf("%d ",rand()%2);		//[0,1] 
	printf("\n\n");
	for(int i = 0;i<10;i++)
		printf("%d ",rand()%5+3);	//[3,7]
	printf("\n\n");

	//生成大于32767的数 ,1.0*rand()/RAND_MAX随机生成一比例 
	for(int i = 0;i<10;i++)
		printf("%d ",(int)(round(1.0*rand()/RAND_MAX*50000+10000)));//[10000,60000]
	return 0;
}

Fast random row

#include<stdio.h>
#include<stdlib.h>
#include <time.h> 
#include <math.h> 
int randPartition(int A[],int left,int right){
	int p = round(1.0*rand()/RAND_MAX*(right-left)+left);
	int t = A[p];
	A[p] = A[left];
	A[left] = t;
	int temp = A[left];
	while(left < right){
		while(left < right && A[right] > temp)	right--;
		A[left] = A[right];
		while(left < right && A[left] <= temp)	left++;
		A[right] = A[left];
	}
	A[left] = temp;
	return left;
} 
//快速排序,left,right是序列首尾的下标
void quickSort(int A[],int left,int right){
	if(left < right){
		int pos = randPartition(A,left,right);
		quickSort(A,left,pos-1);
		quickSort(A,pos+1,right);
	} 
} 
int main(){
	srand((unsigned)time(NULL));
	int a[] = {1,5,4,8,3,6,7,9,10,25,41,62,26,35};
	quickSort(a,0,13);
	for(int i = 0;i<14;i++)
		printf("%d ",a[i]);
	return 0;
}
Published 26 original articles · won praise 3 · Views 203

Guess you like

Origin blog.csdn.net/qq_41898248/article/details/103794950