剑指 Offer 33. 二叉搜索树的后序遍历序列 递归写法
题目链接
public boolean verifyPostorder(int[] postorder) {
return recur(postorder, 0, postorder.length - 1);
}
boolean recur(int[] postorder, int i, int j) {
// 如果左右指针相交,说明停止
if(i >= j) return true;
// 划分左子树
int p = i;
while(postorder[p] < postorder[j]) p++;
// 划分右子树
int m = p;
while(postorder[p] > postorder[j]) p++;
// 左右子树都满足条件,然后分治
return p == j && recur(postorder, i, m - 1) && recur(postorder, m, j - 1);
}
剑指Offer46
public int translateNum(int num) {
if (num <= 9) {
return 1;
}
int ba = num % 100;
// 此时表示最后一位不可分割,比如例子58,或者09
if (ba <= 9 || ba >= 26) {
return translateNum(num/10);
} else{
// 此时舍弃最后一位 + 舍弃最后两位
return translateNum(num / 10) + translateNum( num / 100);
}
}
剑指 Offer 51. 数组中的逆序对
代码
// 记录答案
public int ans = 0;
public int reversePairs(int[] nums) {
ans = 0;
int length = nums.length;
mergeSort(nums, 0, length -1);
return ans;
}
public void mergeSort(int []nums, int left, int right) {
// 分治结束的标志
if (left >= right) {
return;
}
// 求中点,划分左右两个区间,递归排序
int mid = (left + right) / 2;
mergeSort(nums, left, mid);
mergeSort(nums, mid + 1, right);
// 利用一个辅助数组,开始对左右两个排序后的区间进行合并
int l = left, r = mid + 1, cur = 0;
int []temp = new int[right - left + 1];
while (l <= mid && r <= right) {
// 当前左区间更小
if (nums[l] <= nums[r]) {
temp[cur++] = nums[l++];
// 当右区间更小
} else{
// 当前左区间的所有数字,和当前右区间当前指向的数字,形成了逆序对
// 左区间 5 7, 右区间 4 6 , 当前5 7,和4 都形成了逆序对
ans += mid - l + 1;
temp[cur++] = nums[r++];
}
}
// 左区间有剩余
while (l <= mid) {
temp[cur++] = nums[l++];
}
// 右区间有剩余
while (r <= right) {
temp[cur++] = nums[r++];
}
// 将排序好的数组, 赋值给原来的数组
for (int i = 0;i < temp.length; i++) {
nums[left++] = temp[i];
}
}