本来对自己的自学能力和控制力很有信心,尝试自刷了一次,发现自己debug能力太弱了……经常陷在bug里,也没人答疑。索性花钱加了训练营……算是为找工作花的第一笔钱钱……一定能坚持!
704.二分查找
二分法使用的线索提示在“非递减”序列,总之是要经过排序的一堆数
# 左闭右开区间写法
#right的取值比索引最大值大的时候为右开区间,此时判断后赋值也需要比能取的值大1
def search(self, nums: List[int], target: int) -> int:
left = 0
right = len(nums)
while left < right:#right不能取,因此不能带等号
mid = (left+right)//2
if nums[mid] < target:#在右区间
left = mid+1 #要+1
elif nums[mid] > target:#在左区间
right = mid # 不可以取mid-1,应该始终比期待值大1
else:
return mid
return -1
# 左闭右闭区间
# right要为能取的值
class Solution:
def search(self, nums: List[int], target: int) -> int:
left = 0
right = len(nums)-1
while left <= right:
mid = (left+right)//2
if nums[mid] < target:#在右区间
left = mid+1
elif nums[mid] > target:#在左区间
right = mid-1
else:
return mid
return -1
自刷时已经学过了,所以这次没有看基本知识直接写的代码,发现还是会有容易错的地方。
1、不熟悉While语法。While 中无返回值,则返回While后的一句。while是一个循环,出现会一直把While中的部分一直循环完毕再往下
2、两种区间写法,什么时候带等号运用不熟悉(也不算完全理解)
而且只能做这种死题,不会灵活运用
二分拓展.34. 在排序数组中查找元素的第一个和最后一个位置
二分的拓展应用,核心都是找到target,但是与基础二分不同的是要多一个验证条件,就是左边的数要比target小,右边的数要比target大。否则就需要继续缩短查找范围。
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
def leftborder(nums,target):
left = 0
right = len(nums)-1
while left<=right:
mid = (left+right)//2
if nums[mid]<target:#在右区间
left = mid+1
elif nums[mid]>target:#在左区间
right = mid-1
else :
if mid==0 or nums[mid-1]<nums[mid]:
return mid
else :
right = mid-1#继续向左找
return -1
def rightborder(nums,target):
left = 0
right = len(nums)-1
while left<=right:
mid = (left+right)//2
if nums[mid]<target:#在右区间
left = mid+1
elif nums[mid]>target:#在左区间
right = mid-1
else :
if mid==len(nums)-1 or nums[mid+1]>nums[mid]:
return mid
else :
left = mid+1 #继续向右找
return -1
left=leftborder(nums,target)
right=rightborder(nums,target)
return [left,right]
二刷忽然大彻大悟啊!!!做起来怎么比一刷快这么多,而且这个逻辑完全理解!!!就是找target的位置,不然就返回计算后的left的索引
感觉还是归因于昨天对while的用法忽然通透!!
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left = 0
right = len(nums)-1
while left<=right:
mid = (left+right)//2
if nums[mid]<target:#在右区间
left = mid+1
elif nums[mid]>target:#在左区间
right = mid-1
else :
return mid
return left
27、移除元素
返回数组值时,Python不支持nums[0:j] 这种写法?
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
j = 0
for i in range(len(nums)):
if nums[i] != val:
nums[j] = nums[i]
j += 1
return j
不标准写的双指针法,i是快指针,j是慢指针。
我理解的暴力法怎么原来就是双指针……
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
left = 0
right = len(nums)-1
while left <= right:
while left<=right and nums[left] != val:#找到第一个val值出现的位置,
left += 1
while left<=right and nums[right] == val:#找到右边第一个不为val的位置
right -= 1
if left < right :
nums[left] = nums[right]#把链各个值位置交换,把前面等于val的值换到后面
left += 1
right -= 1
return left
开始觉得挺绕的,原来是不理解While函数的用法。要看成一个整体把While循环完才会运行下一步。而不是只运行一次就往下。