leetcode1095. 山脉数组中查找目标值
给你一个 山脉数组 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,3,3,2,1]这种,或者[1,2,2,3,1]这种。但是题里面说了只有大于小于,想复杂了。
看着长,其实就是3次二分,第一次不太好找,后两次是一样的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
class Solution { public int findInMountainArray(int target, MountainArray mountainArr) { int left = 0, right = mountainArr.length() - 1; int ll = left, rr = right; int top = 0; int ans = 0; while (ll <= rr) { int mid = (ll + rr) >> 1; int midl = mid - 1, midr = mid + 1; if (mid - 1 >= 0) midl = mid - 1; if (mid + 1 < mountainArr.length()) midr = mid + 1; if (mountainArr.get(mid) > mountainArr.get(midl) && mountainArr.get(mid) > mountainArr.get(midr)) { top = mid; break; } if (mountainArr.get(midl) < mountainArr.get(midr)) { ll = mid + 1; } else { rr = mid - 1; } } ans = binUpSearch(0,top,mountainArr,target); if (ans == -1) { ans = binDownSearch(top,mountainArr.length() - 1,mountainArr,target); } return ans; } public int binDownSearch(int left, int right, MountainArray mountainArr, int target) { if (left > right) { return -1; } int l = left, r = right; int situation = -1; while (l <= r) { int mid = (l + r) >> 1; int cur = mountainArr.get(mid); if (cur == target) { return mid; } if (cur < target) { r = mid - 1; } else { l = mid + 1; } } return -1; } public int binUpSearch(int left, int right, MountainArray mountainArr, int target) { if (left > right) { return -1; } int l = left, r = right; int situation = -1; while (l <= r) { int mid = (l + r) >> 1; int cur = mountainArr.get(mid); if (cur == target) { return mid; } if (cur < target) { l = mid + 1; } else { r = mid - 1; } } return -1; } }
|
leetcode 90/100