Leetcode刷题_二分查找

4.24

换了一本新书来跟着练leetcode,逻辑跟我高中做物理差不多,分类型分模块

数组的二分查找,掌握全闭区间[left, right]的方式吧,关于这个方法的要点:

1. while的时候需要用到<=符号

2. if target > nums[middle]的时候,middle要+1,因为他已经>middle了,说明本来就不会取这个值了(多余的取,浪费时间

704. 二分查找

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left = 0
        right = len(nums) - 1

        while left <= right:
            if target > (nums[left] + nums[right]) / 2:
                left = (left + right) // 2
            elif target < (nums[left] + nums[right]) / 2:
                right = (left + right) // 2
            elif target == (nums[left] + nums[right]) / 2:
                return (left + right) // 2
        return -1

 麻木了,又双叒超时了

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left = 0
        right = len(nums) - 1
        while left <= right:
            middle = (left + right) // 2
            if target > nums[middle]:
                left = middle
            elif target < nums[middle]:
                right = middle
            elif target == nums[middle]:
                return middle
        return -1

跟上面同质,所以也超时了,又去看了一下二分查找的内容,发现在闭区间下,若target > nums[middle],其实说明nums[middle]这个位置可以不考虑了,所以左边区间需要选middle + 1        :

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left = 0
        right = len(nums) - 1
        while left <= right:
            middle = (left + right) // 2
            if target > nums[middle]:
                left = middle + 1
            elif target < nums[middle]:
                right = middle - 1
            elif target == nums[middle]:
                return middle
        return -1

4.26

34. 在排序数组中查找元素的第一个和最后一个位置

题目上问时间复杂度logn,那就是妥妥的二分查找了

class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        left = 0
        right = len(nums) - 1
        while left <= right:
            middle = (left + right) // 2
            if target < nums[middle]:
                right = middle - 1
            elif target > nums[middle]:
                left = middle + 1
            else:
                first = middle
                last = middle
                if target == nums[first - 1]:
                    first -= 1
                if target == nums[last + 1]:
                    last += 1
                if first != last:
                    return[first, last]
                if first == last:
                    return[first]
        return[-1, -1]

 嵌套了无数个if,写的时候感觉不太对,但是又说不好问题出在哪里,运行果然报错了

6.3

上次刷题真的是上辈子了,经过了一个月的实习,感觉自己在代码这部分还是精进了不少。

但是刷题确实就停滞不前了。

回到上一道题,好久没做了,感觉还是得先看看

算了,34真的有点打脑壳,我先做35吧

35. 搜索插入位置

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        left = 0
        right = len(nums) - 1

        while left + 1 < right:
            middle = (left + right) // 2
            if target < nums[middle]:
                right = middle
            elif target > nums[middle]:
                left = middle
        return left + 1

太久没写了,乃至写了都不知道写了个什么丑东西,直接超出时间限制了

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        left = 0
        right = len(nums) - 1

        while left <= right:
            middle = (left + right) // 2
            if target < nums[middle]:
                right = middle - 1
            elif target > nums[middle]:
                left = middle + 1
            elif target == nums[middle]:
                return middle
        return right + 1

 看答案的写法,最后这个right + 1是满足数组为空的情况,最后这句直接返回left也可以,呜呜呜我怎么那么厉害!(bushi

6.13

终于在学习与分手中找到了自洽的方向:

34. 在排序数组中查找元素的第一个和最后一个位置

class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        def rightBound(nums: List[int], target: int) -> int:
            left, right = 0, len(nums) - 1
            rightbound = -2
            while left <= right:
                middle = (left + right) // 2
                if nums[middle] > target:
                    right = middle - 1
                else:
                    left = middle + 1
                    rightbound = left
            return rightbound
        
        def leftBound(nums: List[int], target: int) -> int:
            left, right = 0, len(nums) - 1
            leftbound = -2
            while left <= right:
                middle = (left + right) // 2
                if nums[middle] >= target:
                    right = middle - 1
                    leftbound = right
                else:
                    left = middle + 1
            return leftbound

        rightbounder = rightBound(nums, target)
        leftbounder = leftBound(nums, target)
        if rightbounder == -2 or leftbounder == -2:
            return [-1,-1]
        elif rightbounder > leftbounder + 1:
            return [leftbounder + 1, rightbounder - 1]
        else:
            return [-1,-1]

多少还是有点问题:

1. 里面的函数是可以写作带self的,但是需要在后面调用的时候加上self

def rightBound(self, nums: List[int], target: int) -> int:

2.

第一个return是一开始的列表为空的情况

第二个return是正常可以查找到的情况

第三个return是列表数字很多但是没有target的情况

additional way

class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        try:
            leftbound = nums.index(target)
            left, right = 0, len(nums) - 1
            while left <= right:
                middle = (left + right) // 2
                if nums[middle] > target:
                    right = middle - 1
                if nums[middle] <= target:
                    left = middle + 1
                    rightbound = left
            return [leftbound, rightbound - 1]
        except:
            return [-1,-1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值