852. Peak Index in a Mountain Array(python+cp)(以及尋找排序陣列中絕對值最小的值)
題目:
Let’s call an array
A
a mountain if the following properties hold:A.length >= 3
There exists some0 < i < A.length - 1
such thatA[0] <A[1] < ... A[i-1] < A[i] > A[i+1] > ... > A[A.length - 1]
Given an array that is definitely a mountain, return anyi
such thatA[0] <A[1] < ... A[i-1] < A[i] > A[i+1] > ... > A[A.length - 1]
. Example 1:Input: [0,1,0] Output: 1
Example 2:
Input: [0,2,1,0] Output: 1
Note:
3 <= A.length <= 10000
0 <= A[i] <= 10^6
A is a mountain, as defined above.
解釋: 二分查詢的應用,尋找山峰的峰值。 二分查詢python程式碼:
def BinarySearch(nums,target):
left,right=0,len(nums)-1
#注意這裡一定要是"<="
while(left<= right):
middle=left+(right-left)//2
if nums[middle]==target:
return middle
#注意這裡left和right的更新
elif nums[middle]<target:
left=middle+1
else:
right=middle-1
return -1
nums=[1,2,3,4,5,6,7,8,9]
target=1
print (BinarySearch( nums,target))
這道題目,只需要比較mid
和mid+1
所指向的值,因為考慮到mid+1
,所以迴圈的條件是left<right
,返回值是left
(若,條件是left<=right的話,當right和left都指向最後一個元素時,此時mid
也指向最後一個元素,mid+1
不在範圍內),同時要注意left
和right
的更新,
若 nums[mid]<nums[mid+1]
,此時mid
一定在山峰的左邊,所以更新 left=mid+1
,
若 nums[mid]>=nums[mid+1]
,此時mid
可能在山峰的右邊,也有可能是山峰本身,所以不能是right=mid-1
,而應該是 right=mid
,這樣做是為了防止mid
是山峰本身的時候漏掉了山峰,進而又跳到了山峰左邊的情況導致求不出值的情況。
python程式碼:
class Solution(object):
def peakIndexInMountainArray(self, A):
"""
:type A: List[int]
:rtype: int
"""
n=len(A)
left,right=0,n-1
while left<right:
mid=left+(right-left)//2
if A[mid]<A[mid+1]:
left=mid+1
else:
right=mid
return left
c++程式碼:
class Solution {
public:
int peakIndexInMountainArray(vector<int>& A) {
int left=0,right=A.size()-1;
while(left<right)
{
int mid=left+(right-left)/2;
if(A[mid]<A[mid+1])
left=mid+1;
else
right=mid;
}
return left;
}
};
拓展: 找到一個排好序的陣列中絕對值最小的元素。 python程式碼:
def findMinAbs(nums):
left,right=0,len(nums)-1
while(left<right):
mid=left+(right-left)//2
if nums[mid]==0:
return nums[mid]
#注意這裡對left和right的更新方式,因為不確定mid是不是絕對值最小的
#所以不能用mid+1和mid-1來更新left和right
elif nums[mid]>0:
right=mid
else:
left=mid
if (right-left==1):
return nums[left] if abs(nums[left])<abs(nums[right]) else nums[right]
nums1=[-9,-8,-7,-6,-2,0,1,2,3,4,5]
nums2=[2,3,4,5,6,7]
nums3=[-9,-8,-7,-6,-2]
nums4=[-9,-8,-7,-6,-2,3,4,5]
nums5=[-9,-8,-7,-6,3,4,5]
print(findMinAbs(nums1))
print(findMinAbs(nums2))
print(findMinAbs(nums3))
print(findMinAbs(nums4))
print(findMinAbs(nums5))
總結: 二分查詢本身很容易,但是對於迴圈判斷條件和更新指標的時候有很多細節是值得注意的,二分查詢有很多拓展應用。