1.题:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。
- #注意是递增数列 双指针法 往中间走,i指向第一个元素,j指向最后一个元素。
如果这两个元素的和等于target,则输出这两个元素
如果比target大,让j往前移动一个
如果比target小,让i往后移动一个
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
i,j=0,len(nums)-1
while i<j:
if nums[i]+nums[j]<target:
i+=1
elif nums[i]+nums[j]>target:
j-=1
else:
return [nums[i],nums[j]]
return []
- #哈希表 妙用 直接根据键访问值
遍历数组元素,在哈希表中查找sum-array[i],若是没找到,将此信息计入哈希表 ,找到便返回
class Solution:
def FindNumbersWithSum(self , array: List[int], sum: int) -> List[int]:
n=len(array)
dic={}
for i in range(n):
tmp=sum-array[i]
if tmp not in dic:
dic[array[i]]=i#键值对应下标(无实际意义什么都行)
else:
return [tmp,array[i]]#找到就返回这个
return []#一直没找到
2.题:输入一个正整数 target
,输出所有和为 target
的连续正整数序列
- #双指针 滑动窗口左右边界 每轮判断滑动窗口内元素和s=i+...+j与目标值target的大小关系
若大于target,则移动左边界i;
若小于target,则移动右边界j 以增大窗口内包括的元素。
class Solution:
def findContinuousSequence(self, target: int) -> List[List[int]]:
i,j,s,res=1,2,3,[]
while i<j:
if s>target:
s-=i
i+=1
elif s<target:
j+=1
s+=j
else:
res.append(list(range(i,int(j)+1)))#滑动窗口向左滑动 继续寻找
s -= i
i += 1
return res
- #巧妙 解方程
左边界i和右边界j target= ((i+j)/2)×(j−i+1) 遍历确定左边界i时 通过target和i解出j 看j是不是整数 且j要大于i
class Solution:
def findContinuousSequence(self, target: int) -> List[List[int]]:
i,j,res=1,2,[]
while i <j:
j = (-1 + (1 + 4 * (2 * target + i * i - i)) ** 0.5) / 2
if i < j and j == int(j):#判断解j是否满足条件
res.append(list(range(i,int(j)+1)))
i+=1
return res
3.题:给你一个整数数组 nums
和一个整数 k
,请你统计并返回 该数组中和为 k
的子数组的个数 。
#非单调数列 不能保证左右指针移动带来有效改变(一定变大或变小)!子数组就是连续的
- #前缀和加哈希表(‘子数组的和’相关问题考虑前缀和)
在遍历的过程中构建前缀和sum
找sum- k在前面的数组中是否存在 即判断 当前位置前缀和减去之前某一位的前缀和等于目标值k
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
dic,res,sum={},0,0
dic[0]=1#或者直接 dic={0:1}
for i in range(len(nums)):
sum+= nums[i]#前缀和
tmp=sum-k#比目标值k多出多少
if tmp in dic:#判断多出的值tmp能不能很好的去掉
res+=dic[tmp]#有多少种方式的和等于tmp
dic[sum]=dic.get(sum,0)+1#记录 前缀和 出现次数
return res
- #暴力枚举 枚举考虑以i结尾的子数组 是否和为k
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
n,res=len(nums),0
for i in range(n):
sum=0
for j in range(i,-1,-1):#考虑0-i位置作为子数组的开头
sum+=nums[j]
if sum==k:
res+=1
return res