public static int getMax (int[] arr, int L ,int R){
return process (arr,0,arr.length-1);
}
// arr[L..R]范围上求最大值
public static int process (int[] arr, int L ,int R){
if (L==R){// arr[L..R]范围上只有一个数,,直接返回, base case
return arr[L];
}
int mid = L +((R -L)>>1); //中点 右移一位相当于(R-L)/2
//十进制右移一位除10 2进制除2 右移一位相当一前面加个0 就是一半
// 直接写(L+R)/2 数组可能会直接溢出
int leftMax = process(arr,L,mid);
int rightMax = process(arr,mid+1,R);
return Matn.max(leftMax,rightMax);
// 相当于递归求最大值
}
递归行为的执行流程
T(N) = a *T(N/b)+O(N^d) master 公式
母 次 子
N 代表数据规模 b 子问题的数据规模 a 子问题的调用次数 后面的剩下的过程复杂度
a= 0 b=2 d=0 例子
T(N) = 2 *T(N/2+O(N^0)
三种情况
logba <d O(N^d)
logba>d O(N^logba)
归并排序
while(p1<= M&& p2 <=R)
{
if(arr[p1]<=arr[p2]){
help[i]=arr[p1];
i++;
p1++;
}
else
{
help[i]=arr[p2];
i++;
p2++;
}
}
// 将剩余的数存入新数组中,只会进入其中一个循环 p1越界或p2越界
while(p1<=M){
help[i]=arr[p1];
i++;
p1++;
}
while(p2<=M){
help[i]=arr[p2];
i++;
p2++;
}
while(p1<=m &&p2<=r){
//如果arr[p1]<arr[p2] p2 右边的数都比 P1大(r-p2+1)就是p2右边所有数的数量
res + = arr[p1]<arr[p2]?(r-p2+1)*arr[p1]:0;
// 两个指针交替比较 前进
help[i++]=arr[p1]<arr[p2]?arr[p1++]:arr[p2++];
}
荷兰国旗问题
1,[i]<=num,[i]和<=区的下一个数交换,<=区右扩,i++
2,[i]>num,i++
第二种情况
快速排序1.0
快速排序2.0 相当于荷兰国旗问题
两种排序方法时间复杂度都是O(N^2)
最坏情况
快速排序3.0 随机选一个数进行划分 时间复杂度 变为O(N*logN)
// arr[1…r] 排好序