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))

总结:
二分查找本身很容易,但是对于循环判断条件和更新指针的时候有很多细节是值得注意的,二分查找有很多拓展应用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值