1、master公式求递归的时间复杂度
T(N) = a*T(N/b) + O(N^d)
- log(b,a) > d -> 复杂度为O(N^log(b,a))
- log(b,a) = d -> 复杂度为O(N^d * logN)
- log(b,a) < d -> 复杂度为O(N^d)
2、归并排序(合并的时候,相等值那么左边先放,就能实现稳定性)
第一步:左边整体有序
第二步:右边整体有序
第三步:左右整合成完全有序(耗费空间o(n))
时间复杂度根据master公式求得 T(n) = 2 * T(n/2) + o(n) = o(N * logN )
3、小和问题
解法:
利用归并排序,维护左右部分有序,用下标p1遍历左部分,p2遍历右部分。
在整合左右部分为有序时,可以进行小和的计算。
当arr[ p1 ] < arr[ p2 ] 时,此时产生的小和数为 arr[ p1 ] * ( r - p2 + 1) 。然后把arr [ p1 ]放到帮助数组中, p1++。
否则直接把arr[ p2 ] 放到帮助数组, p2++;
public int smallSum(int[] arr) {
if(arr == null || arr.length < 2)
return 0
return merge(arr, 0, arr.length - 1);
}
public int merge(int[] arr, int l, int r) {
if(l == r)
return 0;
int mid = ((l+r)>>1);
return merge(arr, l, mid) +merge(arr, mid + 1, r)+ exchange(arr,l,r);
}
int exchange(int[] arr, int l, int r) {
int mid = ((l+r)>>1);
int p1 = l, p2 = mid+1;
int arr2[] = new int[r-l+1];
int index = 0;
int tmp = 0;
while (p1 <= mid && p2 <= r) {
if (arr[p1] < arr[p2]) {
//右边大
tmp += arr[p1] * (r - p2 + 1);
arr2[index++] = arr[p1++];
}else
arr2[index++] = arr[p2++];
}
while (p1<=mid){
arr2[index++] = arr[p1++];
}
while (p2<=r){
arr2[index++] = arr[p2++];
}
index = 0;
while (l<=r){
arr[l++] = arr2[index++];
}
return tmp;
}
4、逆序数问题
求和过程中,当 arr[ p1 ] > arr[ p2 ],res += mid-p1+1