二分查找

山脉数组中查找目标值
🤷‍♀️ 首先,本题的解决思路很明确
这种「分段数组查找目标值」问题,都可以通过将数组分段,从而转化成我们熟悉的「有序数组查找目标值」问题!这个我在前天的打卡题「33.搜索旋转排序数组」的题解《多思路完全攻略,🤷‍♀️必须秒懂!》的「思路一」中讲解过了,欢迎观康~

🤷‍♀️ 好了好了知道用2分了,可是下标总是玩不转,怎么办 QAQ
相信大家都会下面这个 「基础二分模板」:

public int search(int[] nums, int target) {
int lo = 0, hi = nums.length - 1, mid = 0;
while (lo <= hi) {
mid = lo + (hi - lo) / 2;
if (nums[mid] == target) {
return mid;
}
if (nums[mid] < target) {
lo = mid + 1;
} else {
hi = mid - 1;
}
}
return -1;
}
1、为啥是 lo = mid + 1,hi = mid - 1 而不能 lo = mid, hi = mid 呢?
看循环条件 while(lo <= hi) 可知,当 lo 和 hi 差值为 1 或 0 的时候仍然会继续循环,此时 mid 的值就不更新了,为了防止 lo 和 hi 也不更新从而死循环,所以这里 +1 和 -1 不能丢哦。

2、这个基础二分模板的优势和弊端是啥呢?
好处是对于「有序数组查找目标值」很方便呢!
坏处是局限性太强,对于其他二分问题就很鸡肋,比如本题查找峰值,需要在原模板基础上加上特殊的条件分支以及各种边界判断,于是提交一次错一次,面向测试编程哈哈哈,最后终于终于把下标调整对了!可下一次做的时候还要从头再错一遍。。。S。。A。。D。。。。

🌝于是,终于轮到我「万能二分模板」出场了!
我做的 「所有(手动加粗)」 二分题都直 无脑 套这个模板的,屡试不爽呢 > <, 再也不用担心二分写错啦。
下面直接贴代码:

代码中「查找峰顶」用的是「万能二分模板」
找到峰顶后在两段「有序数组中查找目标值」用的是上面介绍的「基础二分模板」(当然也可以用万能模板啦,万能模板就是很万能>o <)
class Solution {
public int findInMountainArray(int target, MountainArray mountainArr) {
// 先找到峰顶索引 peakIdx
int lo = 0, hi = mountainArr.length() - 1;
while (lo + 1 < hi) {
int mid = lo + (hi - lo) / 2;
int midVal = mountainArr.get(mid);

        if (midVal > mountainArr.get(mid - 1)) {
            lo = mid;
        } else {
            hi = mid;
        } 
    }
    int peakIdx = mountainArr.get(lo) > mountainArr.get(hi)? lo: hi;

    
    // 根据峰顶将山脉数组分为「升序数组」和「降序数组」两段,分别进行二分查找
    int idx = binSearch(mountainArr, 0, peakIdx, target, true);
    return idx != -1? idx: binSearch(mountainArr, peakIdx + 1, mountainArr.length() - 1, target, false);
}

private int binSearch(MountainArray mountainArr, int lo, int hi, int target, boolean asc) {
    while (lo <= hi) {
        int mid = lo + (hi - lo) / 2;
        int midVal = mountainArr.get(mid);
        
        if (midVal == target) {
            return mid;
        }
        if (midVal < target) {
            lo = asc? mid + 1: lo;
            hi = asc? hi: mid - 1;
        } else {
            hi = asc? mid - 1: hi;
            lo = asc? lo: mid + 1;
        }
    }
    return -1;
}

}

作者:sweetiee
链接:https://leetcode-cn.com/problems/find-in-mountain-array/solution/shi-shi-hou-ji-chu-wo-de-mo-neng-er-fen-mo-ban-lia/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值