1. 程式人生 > >852. Peak Index in a Mountain Array(python+cp)(以及尋找排序陣列中絕對值最小的值)

852. Peak Index in a Mountain Array(python+cp)(以及尋找排序陣列中絕對值最小的值)

題目:

Let’s call an array Aa mountain if the following properties hold: A.length >= 3 There exists some 0 < i < A.length - 1such that A[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 that A[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))

這道題目,只需要比較midmid+1所指向的值,因為考慮到mid+1,所以迴圈的條件是left<right,返回值是left(若,條件是left<=right的話,當right和left都指向最後一個元素時,此時mid也指向最後一個元素,mid+1不在範圍內),同時要注意leftright的更新, 若 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))

總結: 二分查詢本身很容易,但是對於迴圈判斷條件和更新指標的時候有很多細節是值得注意的,二分查詢有很多拓展應用。