文档讲解:代码随想录
视频讲解:手把手带你撕出正确的二分法 | 二分查找法 | 二分搜索法 | LeetCode:704. 二分查找_哔哩哔哩_bilibili
数组中移除元素并不容易! | LeetCode:27. 移除元素_哔哩哔哩_bilibili
状态:略懂
LeetCode:704.二分查找
思路:二分法就是在数组里将数组长度一分为二,找目标值是否在这个数组里,如果在,返回它的下标。(比从头到尾顺序查找效率要高一点)
有点像猜大小,我在1到100里取一个数,比如80,别人猜:
“比50大吗?”
"对!"
"比75大吗?"
“对!”
“比87大吗?”
“不对!”
“比81大吗?”
“不对!”
“比78大吗?”
“不对!”
“是80吗?”
“恭喜你答对了!”
(是不是比1,2,3........一个个猜效率高)
Python:
(版本一)左闭右闭区间
class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) - 1 # 定义target在左闭右闭的区间里,[left, right]
while left <= right:
middle = left + (right - left) // 2
if nums[middle] > target:
right = middle - 1 # target在左区间,所以[left, middle - 1]
elif nums[middle] < target:
left = middle + 1 # target在右区间,所以[middle + 1, right]
else:
return middle # 数组中找到目标值,直接返回下标
return -1 # 未找到目标值
(版本二)左闭右开区间
class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) # 定义target在左闭右开的区间里,即:[left, right)
while left < right: # 因为left == right的时候,在[left, right)是无效的空间,所以使用 <
middle = left + (right - left) // 2
if nums[middle] > target:
right = middle # target 在左区间,在[left, middle)中
elif nums[middle] < target:
left = middle + 1 # target 在右区间,在[middle + 1, right)中
else:
return middle # 数组中找到目标值,直接返回下标
return -1 # 未找到目标值
27. 移除元素
题目链接:. - 力扣(LeetCode)
思路:给定一个数组,给一个目标值,在数组中删除等于这个目标值的元素,然后返回新数组的大小
这里用到双指针:用一个快慢指针,快指针不能等于目标值,然后在数组长度的循环里,把快指针赋给慢指针(也就是从左到右遍历,不要删除的目标元素,重新搞一个数组)
Python
(版本一)快慢指针法
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
# 快慢指针
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
(版本二)暴力法
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
i, l = 0, len(nums)
while i < l:
if nums[i] == val: # 找到等于目标值的节点
for j in range(i+1, l): # 移除该元素,并将后面元素向前平移
nums[j - 1] = nums[j]
l -= 1
i -= 1
i += 1
return l
# 相向双指针法
# 时间复杂度 O(n)
# 空间复杂度 O(1)
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
n = len(nums)
left, right = 0, n - 1
while left <= right:
while left <= right and nums[left] != val:
left += 1
while left <= right and nums[right] == val:
right -= 1
if left < right:
nums[left] = nums[right]
left += 1
right -= 1
return left