二分查找
704.二分查找
解法一:左闭右开
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
left, right = 0, len(nums)
while left < right:
middle = left + (right - left) // 2
if nums[middle] > target:
right = middle
elif nums[middle] < target:
left = middle + 1
else:
return middle
return left if nums[left] == target else -1
解法二:左闭右闭
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
left, right = 0, len(nums) - 1
while left <= right:
middle = left + (right - left) // 2
if nums[middle] > target:
right = middle - 1
elif nums[middle] < target:
left = middle + 1
else:
return middle
return -1
tips:二分法要学会去找循环不变量。而对于区间的定义是二分法的循环不变量。可以看到两种方式分别为[ ]和[ )。他们的区别在于更新右边界的操作不同。如果是闭区间的话,target有可能在右边界取到,所以在更新的时候要把他的值赋成middle-1(因为nums[middle]不等于target,而nums[middle-1]有可能等于target)。开区间同理。另外,在求middle的时候,如果left+right太大,会造成溢出。所以写成left + (right - left) // 2。
27. 移除元素
解法一:相向双指针
class Solution(object):
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
if nums is None or len(nums) == 0:
return 0
slow = 0
fast = len(nums) - 1
while slow < fast:
while slow < fast and nums[slow] != val:
slow += 1
while slow < fast and nums[fast] == val:
fast -= 1
nums[slow], nums[fast] = nums[fast], nums[slow]
# slow += 1
# fast -= 1
if nums[slow] == val:
return slow
else:
return slow + 1
解法二:快慢指针
class Solution(object):
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
fast = slow = 0
while fast < len(nums):
if nums[fast] != val:
nums[slow] = nums[fast]
slow += 1
fast += 1
return slow
tips:原地修改输入数组—双指针。要建立条件反射(要能想到双指针,可能不一定非得是这个方法)。另,解法一要先判断数组是否为空,否则下面对fast赋值会出错。在写相向双指针的解法时,加上了上面注释的两行代码,导致一直运行出错。思考了一下,slow与fast更新的条件分别在while语句中,如果单独加上那两行的话,每次循环都会不加判断地执行加一减一的操作,没有意义。