分治法
求最大最小元
普通比较次数:2n-3(最大值n-1次,最小值n-2次)
分治法比较次数:3n/2-2次(将原问题分解为大小基本相等的两个子问题,在一个或两个元素的表中求解是很容易的)
void MaxMin(int i,int j,int &max,int &min) { int max1,min1; if(i==j)max=min=l[i];///表中只有一个元素 else if(i==j-1)///表中有两个元素 { if(l[i]<l[j]) {max=l[j];min=l[i];} else {max=l[i];min=l[j];} } else///表中不止两个元素,进行分治 { int m=(i+j)/2; MaxMin(i,m,max,min);///对前半部求解 MaxMin(m+1,j,max,min);///对后半部求解 if(max<max1) max=max1; if(min>min1) min=min1; } }
二分搜索
int search_int() { l=0,r=n-1;///l,r分别是查找左边界和右边界 sort(a,a+n);///数组需要按照有序排列 while(l<=r) { int mid=(l+r)/2;///分割点 if(a[mid]==x) return mid; else if (a[mid]<x) l=mid+1; else r=mid-1; } }
double l,r,mid; for(int i=0;i<100;i++)///设定循环次数,无限逼近答案 { mid=(l+r)/2; if(f(mid)<0) l=mid; else r=mid; }
排序问题
快速排序:
- 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比分割元素小,另外一部分的所有数据都比分割元素大,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列;
- 空间复杂度为O(log2n);
- 时间复杂度比较复杂,最好的情况是O(n),最差的情况是O(n2),所以平时说的O(nlogn),为其平均时间复杂度。
两路合并排序:
- 把两个有序序列合并成一个有序序列。合并方法:比较两个序列中的最小值,输出其中较小者,然后重复此过程,直到其中一个序列为空时,如多另一个还有元素未输出,则将剩余元素依次输出即可;
- 空间复杂度为O(n);
- 时间复杂度最好、最坏、平均都是O(nlogn)。
越努力越幸运!