递归
算中点距离:
- mid = (L + R) / 2 : L + R可能越界
- mid = L + (R - L) / 2 : 更好
- 等同于 L + (R - L) >> 1 : 右移一位比/2要快
递归求一个数组的最大值
1 | public static int getMax(int[] arr) |
master公式
- T(N) = a * T(N / b) + O(N^d)
- T(N) : 母问题规模
- T(N / b) : 子问题的规模
- a : 子问题的调用次数
- O(N^d) : 除去调用之外,剩下的过程的时间复杂度
- 只要是满足子问题等规模的递归,都可以用master公式求解时间复杂度
- logb^a < d O(N^d)
logb^a > d O(N^logb^a)
logb^a == d O(N^d * logN)
归并排序
1 | public static void process(int[] arr, int L, int R) |
小和问题
1 | public static int mergeSort(int[] arr, int L, int R) |
荷兰国旗问题
- 给定一个整形数组和一个数,要求按这个数将数组分为3个区域,> == <。
- [i] < num, [i] 和< 区域下一个交换, <区域右扩, i++
- [i] == num, i++
- [i] > num, [i] 和> 区域前一个交换, >区域左扩, i不变
快速排序
- 快排1.0
- 拿最后一个数num做划分
- 前面的数 <= num的放左边, > num的放右边
- 大于区域的第一个数和num做交换
- 让左侧和右侧重复这个行为
- 快排2.0
- 利用荷兰国旗问题,一次搞定一批相等的数,比1.0快
- 用最后一个数num做划分
- 前面的数分成 <num ==num >num三个区域
- 把num和>num区域第一个数交换
- 让左侧和右侧重复这个行为
- 快排3.0
- 随机选一个数,放在最后,拿它做划分值num
- 时间复杂度变成O(N * logN)
1 | public static void quickSort(int[] arr, int L, int R) |