4.24
换了一本新书来跟着练leetcode,逻辑跟我高中做物理差不多,分类型分模块
数组的二分查找,掌握全闭区间[left, right]的方式吧,关于这个方法的要点:
1. while的时候需要用到<=符号
2. if target > nums[middle]的时候,middle要+1,因为他已经>middle了,说明本来就不会取这个值了(多余的取,浪费时间
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
题目上问时间复杂度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吧
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
终于在学习与分手中找到了自洽的方向:
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]