[转载]剑指 Offer

剑指 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];
        }
    }
posted @ 2020-08-24 21:18  Bears9  阅读(93)  评论(0编辑  收藏  举报