704. 二分查找
文章讲解:programmercarl.com/
思路:
- 二分法
- 易错点:区间问题,在边界判断上容易错,注意左闭右闭和左闭右开。
方法一:左闭右闭[left, right]
#左闭右闭
def search(self, nums: List[int], target: int) -> int:
left = 0
# 左闭右闭 right在区间中
right = len(nums) - 1
while left <= right: # 试想例子left==right,[1,1]为合法的,可以等于
middle = (left + right) // 2
if target < nums[middle]:
# 左闭右闭,前一次包含middle
right = middle - 1
elif target > nums[middle]:
# 左闭右闭,前一次包含middle
left = middle + 1
else:
return middle
return -1
方法二:左闭右闭[left, right)
# 左闭右开
def search(self, nums: List[int], target: int) -> int:
left = 0
# 左闭右开 right不在区间中
right = len(nums)
while left < right: # 关于等号,试想例子left == right, [1,1)不合法,所以不能等
middle = (left + right) // 2
if target < nums[middle]:
#左闭右开 不包含有边界 等于middle没有重复计算
right = middle
elif target > nums[middle]:
#左闭右开 不包含有边界 middle在上一次循环中
left = middle + 1
else:
return middle
return -1
27. 移除元素
数组删除原理:
暴力解法
#暴力
def removeElement(self, nums: List[int], val: int) -> int:
n = len(nums)
i = 0
# 第一层循环找val
while i < n:
if nums[i] == val:
#第二层改数组
for j in range(i, n - 1):
nums[j] = nums[j + 1]
i -= 1 # 避免连续出现val值
n -= 1
i += 1
return n
双指针
双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
定义快慢指针
- 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
- 慢指针:指向更新 新数组下标的位置
# 快慢双指针
def removeElement(self, nums: List[int], val: int) -> int:
slow = 0 # 慢指针是新数组的位置
fast = 0 # 快指针是新数组的元素
l = len(nums)
while fast < l:
# 不等于val时,新数组赋值
# 等于val时,跳过
if nums[fast] != val:
nums[slow] = nums[fast]
slow += 1
fast += 1
return slow
977.有序数组的平方
思路: 相向双指针。较大值放入到结果中,指针向中间移动一位,继续比较。
def sortedSquares(self, nums: List[int]) -> List[int]:
l = 0
r = len(nums) - 1
result = [0] * len(nums)
i = len(nums) - 1 # i表示新数组result的位置,从大到小
while l <= r:
if nums[l] ** 2 >= nums[r] ** 2:
result[i] = nums[l] ** 2
l += 1
else:
result[i] = nums[r] ** 2
r -= 1
i -= 1
return result
今日收获: 二分法的难点(区间的统一),双指针用法