Python数据结构与算法系列(含Leetcode经典题)之二分查找

持续更新中,,,,
微信公众号:leetcode_algos_life,代码随想随记
小红书:412408155
CSDN:https://blog.csdn.net/woai8339?type=blog
抖音【暂未开始,计划开始】:tian72530
知乎【暂未开始,计划开始】:happy001
【CSDN放二维码违规,222333】

竟然说牛客网题目图片违规,,,额,,我单独截屏发下吧,,,

目前,程序员/程序猿面试比较重要的一个点就是数据结构与算法,市面上比较多的数据结构与算法是Java/C/C++实现,Python实现的较少。介于大模型(Large Language Model,LLM)越来越火,Python的应用场景及应用面越来越广,因此,本系列从Python实现的角度进行数据结构与算法系列进行解读。

这里,总体分为几个部分,具体如下(如果有遗漏,大家也可以提出来,博主再补充):
数据结构与算法(Python)版大纲

首先,开始第一个系列,二分查找。

二分查找概念

二分查找本身其实是一个缩放的思想,基础的二分查找问题如下:
针对一个有序数组arr,如何快速查找在有序数组arr中是否存在value这个值,如果存在返回True,否则返回False。

该问题的具体思想如下(假设数组是一个有序升序数组):

  • 定义两个指针,left指向最左边,right指向最右边
  • 当left不超过right时:
    - 取中间元素mid = (left+right)//2
    - 用中间元素mid 和 value 这个值做比较,如果mid=value,返回True。如果mid > value,说明value在左半边,因此,right = mid-1;如果mid<value,说明value比mid还要大,value在右半边,因此,left=mid+1。
  • 都没有时返回False。

因此,二分查找解决四个问题:
1)比较值大于中间值怎么样
2)比较值小于中间值怎么样
3)比较值等于中间值怎么样
4)返回值是什么

这个是基础版本,有很多基于这个版本进行改造的,我们一起看下。(Leetcode近期打开有点慢,从牛客网看下了,选择的都是Python3解题)

开始解题

二分查找是否存在,存在返回其下标,不存在返回-1

题目

在这里插入图片描述

题目解析

这道题目相对比较简单,原来的解题思路中的返回True变成返回mid,返回False变成返回-1就可以了。

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param nums int整型一维数组 
# @param target int整型 
# @return int整型
#
class Solution:
    def search(self , nums: List[int], target: int) -> int:
        # write code here
        if not nums or len(nums) == 0:
            return -1
        
        left, right = 0, len(nums)-1
        while left <= right:
            mid = (left + right) // 2
            if nums[mid] == target:
                return mid
            elif nums[mid] > target:
                right = mid - 1
            else:
                left = mid + 1
        return -1

旋转数组找最小值

题目

在这里插入图片描述

题目解析

这个题目其实挺有意思的,看到log(n)的时间复杂度通常一般都会想到是说,二分查找。但这里存在一个问题是说,二分查找的对比对象是谁。

这里有个“潜规则”:

  • 如果题目中给到了比较值,那么就直接取比较值
  • 如果题目中没有给到比较值,那么取端点值作为比较值。

因此,基于该“潜规则”,我们取右端点进行分析。
回归二分查找需要解决的四大问题:

1)比较值大于中间值怎么样
如果比较值大于中间值,对于该题目来说,对应如下情况:
6,1,2,3
left=0
right=3
mid = (left + right) // 2 = 1 中间值 1
比较值右端点的值为3,
因此,右侧值比中间值大,右侧升序,升序不可能存在最小值。
此时,最小值在mid及其左侧,right = mid

2)比较值小于中间值怎么样
如果比较值小于中间值,对于该题目来说,对应如下情况:
4,5,6,1,2,3
left=0
right=5
mid = (left + right) // 2 = 2 中间值
比较值右端点的值为3,
此时,最小值在mid右侧,left = mid + 1
3)比较值等于中间值怎么样
如果等于的话,相当于右端点的值和中间值相等,此时,没法判断。对应两种情况:

  • 第一种情况:
    1,1,1,1
    这种,这种呢,只能rihgt=right-1一个个缩减区间。

  • 第二种情况
    6,6,4,4,4
    这种呢,也只能rihgt=mid

  • 第三种情况

4,4,6,6,6
这种情况下,因为右侧相等,right=mid

综上,相等的时候,right=right-1一个个缩减区间对比。

4)返回值是什么
返回值呢,两种情况:
一种,空间缩减到只有一个元素,此时直接返回。
另一种,空间缩减到两个元素,此时直接比较两个元素大小,取小的就可以了。

代码

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param nums int整型一维数组 
# @return int整型
#
class Solution:
    def minNumberInRotateArray(self , nums: List[int]) -> int:
        # write code here
        if not nums or len(nums) ==0:
            return -1

        left, right = 0, len(nums) - 1
        while left <= right:
            mid = (left + right) // 2
            if nums[mid] > nums[right]:
                left = mid+1
            elif nums[mid] < nums[right]:
                right = mid
            else:
                right = right - 1
        print(left, right)
        return min(nums[left], nums[right])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值