持续更新中,,,,
微信公众号: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实现的角度进行数据结构与算法系列进行解读。
这里,总体分为几个部分,具体如下(如果有遗漏,大家也可以提出来,博主再补充):
首先,开始第一个系列,二分查找。
二分查找概念
二分查找本身其实是一个缩放的思想,基础的二分查找问题如下:
针对一个有序数组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])