今日任务:
1,704二分查找(简单)
2,27移除元素(简单)
704二分查找
题目链接: 704. 二分查找 - 力扣(LeetCode)
文字讲解:代码随想录
视频讲解:手把手带你撕出正确的二分法 | 二分查找法 | 二分搜索法 | LeetCode:704. 二分查找_哔哩哔哩_bilibili
思路一:左闭右闭
采用二分法查找,循环时左闭右闭(要考虑有等于号)
1)定义左右指针
2)比较中间值与目标值,并重复过程,直到左指针不再<=右指针
中间值大,则右指针更新为(中间值-1)
中间值小,则左指针更新为(中间值+1)
相等的话,则直接返回中间值
3)如果没有目标值,那么返回-1
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
left,right = 0,len(nums)-1
result = -1
while left<=right:
middle = (left + right)//2
# 循环开始是左闭右闭,已经考虑了边界,而mid明确大于target,所以这里right直接在mid上减一位
if nums[middle]>target:
right = middle-1
# 同样的,而mid明确小于target,所以这里left直接mid上进一位
elif nums[middle]<target:
left = middle+1
else :
result = middle
break
return result
思路二:左闭右开
采用二分法查找,循环时左闭右开(不考虑有等于号)
1)定义左右指针
2)比较中间值与目标值,并重复过程,直到左指针不再<右指针
中间值大,则右指针更新为(中间值)
中间值小,则左指针更新为(中间值+1)
相等的话,则直接返回中间值
3)如果没有目标值,那么返回-1
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
# 循环区间左闭右开,所以这里右指针应在右边界外
left ,right = 0, len(nums)
result = -1
while left<right:
middle = (left + right) //2
# 循环开始是左闭右开,没有考虑了右边界,而mid明确大于target,所以这里right直接等于mid
if nums[middle] >target:
right = middle
# 循环开始是左闭右开,已经考虑了左边界,而mid明确大于target,所以这里left直接在mid上加一位
elif nums[middle] < target:
left = middle + 1
else:
result = middle
break
return result
感想:
二分法的题不难,它适用的场所是有序数组,同时题目还强调数组中无重复元素。
两种方法:
一种是left<=right,也就是区间为[left,right],right = len(nums)-1,右指针等于右边界即可。
另一种是left<right,也就是区间为[left,right),right = len(nums),右指针应在右边界外。
27移除元素
题目链接:27. 移除元素 - 力扣(LeetCode)
文字讲解:代码随想录 (programmercarl.com)
视频讲解 :手把手带你撕出正确的二分法 | 二分查找法 | 二分搜索法 | LeetCode:704. 二分查找_哔哩哔哩_bilibili
双指针法:
1)定义两个指针
慢指针slow:更新后的数组下标快指针fast:遍历原始数组的下标
2)当遇到目标值,fast正常走。而slow不动
fast遇到无关值时,把fast的值传给slow,一起正常走
空间复杂度:O(1)
时间复杂度:O(n)
class Solution(object):
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
fast,slow = 0,0
while fast<len(nums):
if nums[fast] == val:
fast +=1
else:
nums[slow] = nums[fast]
slow +=1
fast +=1
return slow
暴力解题法:
当遇到目标值时,所有的值往前面移动,把目标值覆盖掉
class Solution(object):
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
left = 0
right = len(nums) - 1
while left <= right:
if nums[left] == val:
nums[left], nums[right] = nums[right], nums[left]
right -= 1
else:
left += 1
return left
感想:
双指针解法,采用两个标记,可以在原数组上进行变更,不会增加空间复杂度,也不用循环多次,简单很多。