Leetcode日练笔记3 #278 #162 #153 First bad version & Find peak element & Find minimum in rotated array

本文探讨了二分查找算法在解决不同搜索问题中的应用,如找到第一个坏版本、峰值元素和旋转排序数组中的最小值。通过分析不同问题的解题思路,阐述了如何调整终止条件和中值选取策略来确保算法的正确性和效率。同时,文章提到了在某些情况下,微小的改动可能会影响运行时性能的微妙之处。
摘要由CSDN通过智能技术生成

Template 2 是让最后一步只剩2个值,一个是left pointer,另一个是right pointer。如果不管哪个,若和目标值不一致,则两个pointer合并为一个,最后terminate while循环,并post process最后一个值是否与目标值同。不同则输出-1。

(Q:暂时没理解为啥和template 1 不同?先🐴)

# 278 First Bad Version

You are a product manager and currently leading a team to develop a new product. Unfortunately, the latest version of your product fails the quality check. Since each version is developed based on the previous version, all the versions after a bad version are also bad.

Suppose you have n versions [1, 2, ..., n] and you want to find out the first bad one, which causes all the following ones to be bad.

You are given an API bool isBadVersion(version) which returns whether version is bad. Implement a function to find the first bad version. You should minimize the number of calls to the API.

第一次写的:

# The isBadVersion API is already defined for you.
# def isBadVersion(version: int) -> bool:

class Solution:
    def firstBadVersion(self, n: int) -> int:
        l, r = 0, n
        while r - l > 1:
            mid = (l + r)//2
            if isBadVersion(mid):
                l = mid
            else:
                r = mid
        return r

submit之后说n = 2, bad =1的情况下不符。

发现是我的解法是,terminate的条件是最后剩两个值,左边是最后一个good version,右边是第一个bad version。但我这种思路是默认Left pointer所杵的位置一定是good version,right pointer所杵的位置是bad version。所以test case中一旦left pointer起始位置就是bad version,就会输出错误的结果。

只能换一种terminate方式。left 与right pointer 合为一个再输出。l = mid + 1。这样剩一个值的时候一定是我们要的first bad version的值。

改了之后的runtime:

sample solution:

本质没区别。不分析了。 

#162 Find Peak Element

A peak element is an element that is strictly greater than its neighbors.

Given an integer array nums, find a peak element, and return its index. If the array contains multiple peaks, return the index to any of the peaks.

You may imagine that nums[-1] = nums[n] = -∞.

You must write an algorithm that runs in O(log n) time.

解题思路是最后剩一个值,这个值就是所求peak的index。

中值取法是左右标之和加1除以2,相当于最后剩两值时,mid与右标相等。

筛选条件是mid比左边的值大就挪left pointer至中值。反之则右标挪至中值左邻的位置。

class Solution:
    def findPeakElement(self, nums: List[int]) -> int:
        l, r = 0, len(nums)-1
        while r > l:
            mid = (r+l+1)//2
            if nums[mid] > nums[mid-1]:
                l = mid
            else:
                r = mid - 1
        return l

 runtime:

 sample:

中值少了+1一步。不过改了之后

class Solution:
    def findPeakElement(self, nums: List[int]) -> int:
        l, r = 0, len(nums)-1
        while r > l:
            mid = (r+l)//2
            if nums[mid] > nums[mid+1]:
                r = mid
            else:
                l = mid + 1
        return l

反而更慢了。比较玄学……

算了,以后sample解法相差不大的就不分析也不提了。

#153 Find Minimum in Rotated Sorted Array

解题思路:

不考虑rotated了多少次,只判断最小值在中值左边还是右边。判别方法,中值与尾值比大小:> 则在右边。反之则反。最后terminate的condition是左标右标合一,最后剩最小值。

class Solution:
    def findMin(self, nums: List[int]) -> int:
        l, r = 0, len(nums)-1
        while r > l:
            mid = (l + r)//2
            if nums[mid] > nums[-1]:
                l = mid + 1
            else:
                r = mid
        return nums[l]

runtime:

 和31ms的解法一样。就不分析了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值