“山脉数组”

山脉数组中查找目标值

给你一个 山脉数组 mountainArr,请你返回能够使得 mountainArr.get(index) 等于 target 最小 的下标 index 值。

如果不存在这样的下标 index,就请返回 -1

何为山脉数组?如果数组 A 是一个山脉数组的话,那它满足如下条件:

首先A.length >= 3

其次,在 0 < i < A.length - 1 条件下,存在 i 使得:

  • A[0] < A[1] < ... A[i-1] < A[i]
  • A[i] > A[i+1] > ... > A[A.length - 1]

你将 不能直接访问该山脉数组,必须通过 MountainArray 接口来获取数据:

  • MountainArray.get(k) - 会返回数组中索引为k 的元素(下标从 0 开始)
  • MountainArray.length() - 会返回该数组的长度

注意:

MountainArray.get 发起超过 100 次调用的提交将被视为错误答案。此外,任何试图规避判题系统的解决方案都将会导致比赛资格被取消。

为了帮助大家更好地理解交互式问题,我们准备了一个样例 “答案”,请注意这 不是一个正确答案。

示例 1:

输入:array = [1,2,3,4,5,3,1], target = 3
输出:2
解释:3 在数组中出现了两次,下标分别为 2 和 5,我们返回最小的下标 2。

示例 2:

输入:array = [0,1,2,4,2,1], target = 3
输出:-1
解释:3 在数组中没有出现,返回 -1。

提示:

  • 3 <= mountain_arr.length() <= 10000
  • 0 <= target <= 10^9
  • 0 <= mountain_arr.get(index) <= 10^9

分析:

  1. target == nums[mid] 时,需要判断 [l, mid-1] 有没有target!!
  2. target > nums[mid]
    • nums[mid] > nums[mid + 1]:峰在左边,二分查找:[l, mid-1]
    • 否则,查找:[mid+1, r]
  3. target < nums[mid]时:
    • target < nums[l]时,说明target只在mid右边会有,查找 [mid+1, r]
    • target < nums[r]时,说明target只能在mid左边,查找 [l, mid-1]
    • 否则 mid 的左右两边都有可能有target由于找到第一个出现的,所以先查找左边的,再查找右边的!!!(不能换)

代码( 双100%):

public int findInMountainArray(int target, MountainArray mountainArr) {
    int len = mountainArr.length();
    if (len < 1){
        return -1;
    }
    return findInMountainArray(target, mountainArr,0,len-1,len);
}
public int findInMountainArray(int target, MountainArray mountainArr, int l, int r, int len){
    // base case
    if (l > r){
        return -1;
    }
    int mid = (l+r)/2;
    int midnum = mountainArr.get(mid);
    // target == nums[mid]
    if (target == midnum){
        int tmp = findInMountainArray(target,mountainArr,l,mid-1,len);
        if (tmp == -1){
            return mid;
        }
    }
    // target  > nums[mid]
    if (target > midnum){
        int tmp = 0;
        if (mid+1 < len && midnum > mountainArr.get(mid+1)){
            return findInMountainArray(target,mountainArr,l,mid-1,len);
        }else{
            return findInMountainArray(target,mountainArr,mid+1,r,len);
        }
    }else
    // target  < nums[mid]
    {
        if (target < mountainArr.get(l)){
            return findInMountainArray(target,mountainArr,mid+1,r,len);
        }else if (target < mountainArr.get(r)){
            return findInMountainArray(target,mountainArr,l,mid-1,len);
        }else {
            int tmp = findInMountainArray(target,mountainArr,l,mid-1,len);
            if (tmp != -1){
                return tmp;
            }else{
                return findInMountainArray(target,mountainArr,mid+1,r,len);
            }
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值