力扣---2020.4.29

1095. 山脈數組中查找目標值

  • 視頻中的二分題目 33 81 153 154 69 875 1300 410
class Solution {
    // 特別注意:3 個輔助方法的分支出奇地一樣,因此選中位數均選左中位數,纔不會發生死循環
    public int findInMountainArray(int target, MountainArray mountainArr) {
        int size = mountainArr.length();
        // 步驟 1:先找到山頂元素所在的索引
        int mountaintop = findMountaintop(mountainArr, 0, size - 1);
        // 步驟 2:在前有序且升序數組中找 target 所在的索引
        int res = findFromSortedArr(mountainArr, 0, mountaintop, target);
        if (res != -1) {
            return res;
        }
        // 步驟 3:如果步驟 2 找不到,就在後有序且降序數組中找 target 所在的索引
        return findFromInversedArr(mountainArr, mountaintop + 1, size - 1, target);
    }

    private int findMountaintop(MountainArray mountainArr, int l, int r) {
        // 返回山頂元素
        while (l < r) {
            int mid = l + (r - l) / 2;
            // 取左中位數,因爲進入循環,數組一定至少有 2 個元素
            // 因此,左中位數一定有右邊元素,數組下標不會發生越界
            if (mountainArr.get(mid) < mountainArr.get(mid + 1)) {
                // 如果當前的數比右邊的數小,它一定不是山頂
                l = mid + 1;
            } else {
                r = mid;
            }
        }
        // 根據題意,山頂元素一定存在,因此退出 while 循環的時候,不用再單獨作判斷
        return l;
    }

    private int findFromSortedArr(MountainArray mountainArr, int l, int r, int target) {
        // 在前有序且升序數組中找 target 所在的索引
        while (l < r) {
            int mid = l + (r - l) / 2;
            if (mountainArr.get(mid) < target) {
                l = mid + 1;
            } else {
                r = mid;
            }

        }
        // 因爲不確定區間收縮成 1個數以後,這個數是不是要找的數,因此單獨做一次判斷
        if (mountainArr.get(l) == target) {
            return l;
        }
        return -1;
    }

    private int findFromInversedArr(MountainArray mountainArr, int l, int r, int target) {
        // 在後有序且降序數組中找 target 所在的索引
        while (l < r) {
            int mid = l + (r - l) / 2;
            // 與 findFromSortedArr 方法不同的地方僅僅在於由原來的小於號改成大於好
            if (mountainArr.get(mid) > target) {
                l = mid + 1;
            } else {
                r = mid;
            }

        }
        // 因爲不確定區間收縮成 1個數以後,這個數是不是要找的數,因此單獨做一次判斷
        if (mountainArr.get(l) == target) {
            return l;
        }
        return -1;
    }
}

面試題36. 二叉搜索樹與雙向鏈表

class Solution {
    Node pre, head;
    public Node treeToDoublyList(Node root) {
        if(root == null) return null;
        dfs(root);
        head.left = pre;
        pre.right = head;
        return head;
    }
    void dfs(Node cur) {
        if(cur == null) return;
        dfs(cur.left);
        if(pre != null) pre.right = cur;
        else head = cur;
        cur.left = pre;
        pre = cur;
        dfs(cur.right);
    }
}

你知道的越多,你不知道的越多。
有道無術,術尚可求,有術無道,止於術。
如有其它問題,歡迎大家留言,我們一起討論,一起學習,一起進步

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章