1、算法流程
- 递归返回条件
- 分段处理
- 合并结果
数据结构:
- 类似二叉树结构
- 或者可以用二分法递归处理的数据结构
典型应用如:快速排序,归并排序
模板
func traversal(root *TreeNode) ResultType {
// nil or leaf
if root == nil {
// do something and return
}
// Divide
ResultType left = traversal(root.Left)
ResultType right = traversal(root.Right)
// Conquer
ResultType result = Merge from left and right
return result
}
2、分治法—归并排序
private void mergeSort(int[] arr, int start, int end) {
if (start >= end) {
return;
}
int mid = (start + end)/2;
mergeSort(arr, start, mid);
mergeSort(arr, mid + 1, end);
merge(arr, start, mid, end);
}
private void merge(int[] arr, int start, int mid, int end) {
int[] tmp = new int[end - start + 1];
int left = start;
int right = mid + 1;
int index = 0;
while (left <= mid && right <= end) {
if (arr[left] > arr[right]) {
tmp[index++] = arr[right++];
} else {
tmp[index++] = arr[left++];
}
}
while (left <= mid) {
tmp[index++] = arr[left++];
}
while (right <= end) {
tmp[index++] = arr[right++];
}
index = 0;
while (start <= end) {
arr[start++] = tmp[index++];
}
}
3、分治法—快速排序
private void quickSort(int[] arr, int start, int end) {
if (start < end) {
int pivot = partition2(arr, start, end);
quickSort(arr, start, pivot - 1);
quickSort(arr, pivot + 1, end);
}
}
- 两边向中间靠拢
private int partition(int[] arr, int start, int end) {
int pivot = (start + end) / 2;
int tmp = arr[pivot];
int left = start;
int right = end;
while (left < right) {
while (arr[left] < tmp && left < pivot) {
left++;
}
if (left < pivot) {
arr[pivot] = arr[left];
pivot = left;
left++;
}
while (arr[right] >= tmp && right > pivot) {
right--;
}
if (right > pivot) {
arr[pivot] = arr[right];
pivot = right;
right--;
}
}
arr[pivot] = tmp;
return pivot;
}
- 前置插入
private int partition2(int[] arr, int start, int end) {
int pivot = arr[start];
int pos = start;
for (int i = start + 1; i <= end; i++) {
if (arr[i] < pivot) {
swap(arr, ++pos, i);
}
}
swap(arr, start, pos);
return pos;
}
private void swap(int[] arr, int num, int num1) {
int k = arr[num];
arr[num] = arr[num1];
arr[num1] = k;
}
4、两个节点的最近根节点
public static Node lowestParentNode(Node root, Node node1, Node node2) {
if (root == null) {
return null;
}
if (root.val == node1.val || root.val == node2.val) {
return root;
}
Node left = lowestParentNode(root.left, node1, node2);
Node right = lowestParentNode(root.right, node1, node2);
if (left != null && right != null) {
return root;
}
return left != null ? left: right;
}