704. 二分查找
方法一:左闭右闭
left=0, right=len(nums)-1即选择左闭右闭,
while(left ?? right) 的符号是< 还是<=, 看等于的时候到底这个左闭右闭区间是否合法,比如[1,1]是合法的,所以应该包含=
left更新是middle+1还是middle?
因为if target>nums[middle],则middle肯定不是我们要找的下标,所以left=middle+1;同理if target<nums[middle]: right=middle-1
class Solution:
def search(self, nums: List[int], target: int) -> int:
l = 0
r = len(nums) - 1
if target < nums[l] or target > nums[r]: return -1
idx = -1
while l <= r:
mid = (r + l) // 2
# mid = l + (r - l) // 2
if target == nums[mid]:
idx = mid
break
elif target > nums[mid]:
l = mid + 1
else:
r = mid - 1
return idx
方法二:左闭右开
class Solution:
def search(self, nums: List[int], target: int) -> int:
l = 0
r = len(nums) # 右开
if target < nums[l] or target > nums[r - 1]: return -1
idx = -1
while l < r: # [1,1) 不再合法,所以不能有等号
mid = l + (r - l) // 2
if target == nums[mid]:
idx = mid
break
elif target > nums[mid]:
l = mid + 1
else:
r = mid
return idx
27. 移除元素
一开始我先想到是否可以用python list方法来直接缩减数组。但这题因为有重复的数字所以不能这样做。也不能转换成set去重再remove,因为会把其他不能删的数字也去重了。
以下为正解:用快慢指针,快指针遍历数组并寻找新数组的所有元素,慢指针标注新数组钟需要被替换的位置。
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
fast = 0
slow = fast
count = 0
while fast < len(nums):
if nums[fast] != val:
nums[slow] = nums[fast]
slow += 1
fast += 1
else:
count +=1
fast += 1
return len(nums) - count
可简化为如果nums[fast]!=val则nums[slow]=nums[fast]然后slow+=1,fast无论怎样要在每个iteration都+1。count其实不需要,因为slow用来收集不等于val的值,所以slow的最终值就是输出数组的长度。简化后的代码为:
def removeElement(self, nums: List[int], val: int) -> int:
slow = 0
for fast in range(len(nums)):
if nums[fast] != val:
nums[slow] = nums[fast]
slow += 1
return slow