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);
}
}
你知道的越多,你不知道的越多。
有道無術,術尚可求,有術無道,止於術。
如有其它問題,歡迎大家留言,我們一起討論,一起學習,一起進步