Leetcode 刷题笔记 (binary search)

这篇博客主要介绍了LeetCode中涉及二分查找算法的几道题目,包括寻找有序数组中目标元素的第一个和最后一个位置、求平方根、找两个有序数组的中位数以及找出有序数组中的唯一元素。博主详细解析了每道题目的解题思路,通过二分法优化搜索过程,提高时间复杂度至O(logn)。此外,还讨论了二分法在处理旋转数组等变种问题的应用。
摘要由CSDN通过智能技术生成

二分法

  1. l = 0, r = 0, mid = (l + r) // 2
  2. 二分法就是首尾双指针 (每轮移位为一个区间)
  3. nums[mid] > target >>> r = mid - 1;else: l = mid + 1
  4. 时间复杂度 O(logn)

34. Find First and Last Position of Element in Sorted Array(medium)

https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/

class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        l = 0
        r = len(nums) - 1
        res = -1
        while l <= r:
            mid = (l + r) // 2
            if nums[mid] == target:
                res = mid
                break
            elif nums[mid] > target:
                r = mid - 1
            else:
                l = mid + 1
        if res == -1:
            return [-1, -1]
        #step 1 [l, res]--> 有几个res即[1,...,res,res,res]
        l = 0
        r = res
        l_bound = 0
        r_bound = 0
        while l <= r:
            mid = (l+r)//2
            if nums[mid] == target:
                r = mid - 1
                l_bound = mid
            else: 
                l = mid + 1
        l = res
        r = len(nums) - 1
        while l <= r: 
            mid = (l + r) // 2
            if nums[mid] == target:
                r_bound = mid
                l = mid + 1
            else:
                r = mid - 1
        return [l_bound, r_bound]

三轮二分,

  1. 第一轮确认一个target的位置作为mid
  2. 第二轮确认[l , mid] 中间是否还有target
  3. 第三轮[mid , r] 中间是否有target

69. Sqrt(x) (easy)

https://leetcode.com/problems/sqrtx/

class Solution:
    def mySqrt(self, x: int) -> int:
        l = 0
        r = x
        while l <= r:
            mid = (l + r) // 2
            if mid * mid == x:
                return mid
            elif mid * mid > x:
                r = mid - 1
            else:
                l = mid + 1
        return r
        

因为题目取下界故 return r,
因为while循环的推出时[r , l] >>> 为所取平方根的区间

4. Median of Two Sorted Arrays (Hard)

https://leetcode.com/problems/median-of-two-sorted-arrays/

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        nums1.extend(nums2)
        nums1.sort()
        if len(nums1) % 2 == 1:
            return nums1[len(nums1) // 2]
        else: #[0,1,2,3] 4/2 = 2
            return ( nums1[len(nums1) // 2] + nums1[len(nums1) // 2 - 1] ) / 2
            

用py的函数取个巧

34. Find First and Last Position of Element in Sorted Array(medium)

https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/

class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        l = 0
        r = len(nums) - 1
        rst = -1
        while l <= r:
            mid = (l + r) // 2
            if nums[mid] == target:
                rst = mid
                break
            elif nums[mid] > target:
                r = mid - 1
            else:
                l = mid + 1
        if rst == -1:
            return [-1, -1]
        
        l = 0 
        r = rst
        l_bound = 0
        r_bound = 0
        # left side
        while l <= r:
            mid = (l + r) // 2
            if nums[mid] == target:
                #[l,mid,rst] --> [mid, rst] = target
                l_bound = mid
                r = mid - 1
            else:
                #[l, mid, target=rst]
                l = mid + 1
        # right side
        l = rst
        r = len(nums) - 1
        while l <= r:
            mid = (l + r) // 2
            if nums[mid] == target:
                #[rst, mid, r]
                r_bound = mid
                l = mid + 1
            else:
                r = mid - 1
        return [l_bound, r_bound]
            

540. Single Element in a Sorted Array (medium)

https://leetcode.com/problems/single-element-in-a-sorted-array/

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

偶数位后续为相同的数,即nums[even] == nums[even + 1] >>> 左边有序
反之,右边有序
例子如下:

  1. [1,1,2,3,3],2≠3 >>> 无序的出现在[l, mid]
  2. [1,1,2,2,3],2=2 >>> 无序的出现在[mid, r]

二分变种>>> 旋转数组

https://blog.csdn.net/Gowott/article/details/123255475

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值