二分查找
704.二分查找
给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
解决方法
注意把终止条件放在前面,比如这里如果终止条件如果放在后面递归就出不来了(左闭右闭)
class Solution:
def search(self, nums: List[int], target: int) -> int:
def binary(low,high):
if low>high:
return -1
mid=(low+high)//2
tmp=nums[mid]
if target==tmp:
return mid
elif target>tmp:
return binary(mid+1,high)
else:
return binary(low,mid-1)
return binary(0,len(nums)-1)
35.搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n)
的算法。
解决方法
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
def binary(low,high):
mid=(low+high)//2
#python中的//只保留整数部分
if low>high:
return low
tmp=nums[mid]
if target==tmp:
return mid
elif target>tmp:
low=mid+1
return binary(low,high)
else:
high=mid-1
return binary(low,high)
return binary(0,len(nums)-1)
34.在排序数组中查找元素的第一个和最后一个位置
给你一个按照非递减顺序排列的整数数组 nums
,和一个目标值 target
。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target
,返回 [-1, -1]
。
你必须设计并实现时间复杂度为 O(log n)
的算法解决此问题。
解决方法
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
#是不是只要是顺序存储的题目优先想是否为二分查找的变形
#二分找到了一个数,然后往前后走
def binary(low,high):
if low>high:
return -1
mid=(low+high)//2
tmp=nums[mid]
if target==tmp:
return mid
elif target>tmp:
low=mid+1
return binary(low,high)
else:
high=mid-1
return binary(low,high)
a=b=binary(0,len(nums)-1)
if a==-1:
return [a]*2
#front最小为0,back最大为len(nums)-1
front=a-1
back=b+1
while a>0 and nums[front]==nums[a]:
a=front
front=a-1
while b<len(nums)-1 and nums[back]==nums[b]:
b=back
back=b+1
return [a,b]
69.X的平方根
给你一个非负整数 x
,计算并返回 x
的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5)
或者 x ** 0.5
。
解决方法
(不是一个数组也可以用二分查找的思想)
class Solution:
def mySqrt(self, x: int) -> int:
l = 0
r = x
while l <= r:
mid = (l + r) // 2
v = mid ** 2
if v < x:
l = mid + 1
elif v > x:
r = mid - 1
else:
return mid
return r
367.有效的完全平方数
给你一个正整数 num
。如果 num
是一个完全平方数,则返回 true
,否则返回 false
。
完全平方数 是一个可以写成某个整数的平方的整数。换句话说,它可以写成某个整数和自身的乘积。
不能使用任何内置的库函数,如 sqrt
解决方法
(true和false首字母要大写不然识别不出来)
class Solution:
def isPerfectSquare(self, num: int) -> bool:
def binary(low,high):
if low>high:
return False
mid=(low+high)//2
tmp=mid*mid
target=num
if target==tmp:
return True
elif target>tmp:
return binary(mid+1,high)
else:
return binary(low,mid-1)
return binary(0,num)
双指针
27.移除元素
给你一个数组 nums
和一个值 val
,你需要 原地 移除所有数值等于 val
的元素。元素的顺序可能发生改变。然后返回 nums
中与 val
不同的元素的数量。
假设 nums
中不等于 val
的元素数量为 k
,要通过此题,您需要执行以下操作:
- 更改
nums
数组,使nums
的前k
个元素包含不等于val
的元素。nums
的其余元素和nums
的大小并不重要。 - 返回
k
。
解决方法
快慢指针(i充当快指针,index充当慢指针)
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
index=0
for i in range(len(nums)):
if nums[i]!=val:
nums[index]=nums[i]
index+=1
return index
26.删除有序数组中的重复项
给你一个 非严格递增排列 的数组 nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums
中唯一元素的个数。
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
slow=fast=0
while fast<len(nums):
if nums[slow]!=nums[fast]:
slow+=1
nums[slow]=nums[fast]
fast+=1
return slow+1
283.移动零
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
slow=fast=0
while fast<len(nums):
if nums[fast]!=0:
tmp=nums[slow]
nums[slow]=nums[fast]
nums[fast]=tmp
slow+=1
fast+=1