704. 二分查找
解题思路
本题对有序数组寻找目标节点,采用二分法,每次从中间开始与目标值比对后再向左或右收缩区间。
- 时间复杂度:O(log n)
- 空间复杂度:O(1)
方法1:二分法,左闭右闭
class Solution:
def search(self, nums: List[int], target: int) -> int:
# 左闭右闭[left,right]
left, right = 0, len(nums) - 1
while left <= right: # left<=right时候有意义
mid = left + (right - left ) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else: # 注意右边闭区间,mid取不到target,所以要mid-1
right = mid - 1
return -1
方法2:二分法,左闭右开
class Solution:
def search(self, nums: List[int], target: int) -> int:
# 左闭右开[left,right)
left, right = 0, len(nums)
while left < right: #left<right时候有意义
mid = left + (right - left ) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else: # 注意[left,right),本身mid取不到target,right=mid
right = mid
return -1
总结
二分法虽然比较简单,之前区间定义记得不太清楚,导致写代码时候对while条件什么时候用"=",right是mid或mid-1很不肯定。现在牢记左闭右开,左闭右闭两种区间规则,肥肠自信!
27. 移除元素
解题思路
数组插入和删除元素复杂度都是On,原地交换的话需要使用快慢指针,快指针找到新数组的元素(非target),慢指针指向待交换元素,如果遇到非target元素,用fast覆盖slow。
- 时间复杂度:O(n)
- 空间复杂度:O(1)
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
slow, fast = 0, 0
while fast < len(nums):
if nums[fast] != val:
# 两种情况:1 slow和fast指向同一个非target元素 2 slow指向target,fast指向非target
nums[slow] = nums[fast]
slow += 1
fast += 1
return slow
总结
通过使用双指针的方法,我们能够有效地在原数组中移除指定元素,且不需要额外的空间。这种方法不仅高效,而且简单易懂,适用于处理类似的数组操作问题。