一、今日任务
- 二分查找 27. 移除元素
二、二分查找
2.1 题目:704.二分查找
2.2 解题过程
二分查找是一个比较简单的查找方法。所以接下来在记录在解题过程中主要遇到的问题。
2.2.1第一个问题就是查找不到时无法退出循环
解决方法是不断修改left、right的初值,temp的计算公式、left、right的更新公式和while循环的条件。
在解题前就应该确定是左闭右闭还是左开右闭。
在解题时,遇到无法退出循环时,都没有修改while的结束条件。
这里总结的出问题原因还是因为对于解题思路的不清晰。
2.2.2结合随想录文章复习整个题解思路
首先确定二分法的前提:list 有序、无重复。
其次两种解题思路:左闭右闭和左开右闭。这两种方法在初始设置、循环条件和更新时要分别满足其基本思路。
左闭右开代码
# 左闭右开
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
index = -1
left = 0
right = len(nums)
while (left < right):
middle = int((left + right) / 2)
if nums[middle] == target:
index = middle
break
elif nums[middle] > target:
right = middle
else:
left = middle + 1
return index
左闭右闭代码
# 左闭右闭
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
index = -1
left = 0
right = len(nums)-1
while (left <= right):
middle = int((left + right) / 2)
if nums[middle] == target:
index = middle
break
elif nums[middle] > target:
right = middle - 1
else:
left = middle + 1
return index
三、移除元素
3.1 27. 移除元素
3.2 解题过程
题目要求:不额外使用数组空间
这题还是耽误了很久。
第一个原因是题目看出了,应该是移出给定值,而不是保留。这导致思路错乱了很久。
以下是解题代码:
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
left = 0
right = len(nums) - 1
while right >= 0 and nums[right] == val:
right -= 1
if right < 0:
return left
while left <= right:
if nums[left] == val:
nums[left] = nums[right]
nums[right] = val
right -= 1
left += 1
while right >= 0 and nums[right] == val:
right -= 1
if right < 0:
break
return left
使用的是左右指针,右指针始终指向一个保留数字,左指针扫描,出现移出数字,与右指针交换,更新指针。
3.3与随想录解题的差距
随想录中给出了暴力解法、快慢指针法和双向指针法(比自己的解法更加简洁清晰和通用)
暴力解法:从左到右扫描,出现要移除的值,移出,更新数组。
length = len(nums)
i = 0
# 在range(0,length)中,范围会被固定,所以改用while
while i < length:
if nums[i] == val:
for j in range(i+1,length):
nums[j-1] = nums[j]
i -= 1
length -= 1
i += 1
return length
快慢指针法:从两个从0开始的指针,快指针寻找第一个满足条件的值,与慢指针交换,慢指针加1(即确定新数组的第一个位置是谁),快指针继续找,知道快指针遍历完。
# 快慢指针
fast = 0 # 快指针
slow = 0 # 慢指针
size = len(nums)
while fast < size: # 不加等于是因为,a = size 时,nums[a] 会越界
# slow 用来收集不等于 val 的值,如果 fast 对应值不等于 val,则把它与 slow 替换
if nums[fast] != val:
nums[slow] = nums[fast]
slow += 1
fast += 1
return slow
双向指针:左边找最近的移除值,右边找最近的保留值,如果左在左,右在右交换。
left = 0
right = len(nums) - 1
while left <= right:
while left <= right and nums[right] == val:
right -= 1
while left <= right and nums[left] != val:
left += 1
if left < right :
nums[left] = nums[right]
nums[right] =val
left += 1
right -= 1
return left
本文详细介绍了二分查找算法的实现方法及其注意事项,并通过具体示例代码展示了如何进行左闭右闭和左闭右开的二分查找。此外,还探讨了解决移除元素问题的不同策略,包括暴力解法、快慢指针法和双向指针法。
747

被折叠的 条评论
为什么被折叠?



