快慢双指针
左右指针
思路:
固定一个值,然后 while i<j
避免重复:
if nums[n] == nums[n-1] and n > m+1:
while i<j and nums[i+1] == nums[i]:
模版:
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
res = []
nums = sorted(nums)
for m in range(len(nums)):
if nums[m] == nums[m-1] and m > 0:
continue
for n in range(m+1 , len(nums)):
if nums[n] == nums[n-1] and n > m+1:
continue
i = n+1
j = len(nums)-1
while i < j:
q = nums[m] + nums[n] + nums[i] +nums[j]
if q > target:
j -= 1
elif q < target:
i += 1
else:
res.append([nums[m] , nums[n] , nums[i] , nums[j]])
while i<j and nums[i+1] == nums[i]:
i+=1
while i<j and nums[j-1] == nums[j]:
j-=1
i+=1
j-=1
return res
15. 三数之和
16. 最接近的三数之和
18. 四数之和
前缀和
class Solution:
def countRangeSum(self, nums: List[int], lower: int, upper: int) -> int:
res, pre, now = 0, [0], 0
for n in nums:
now += n
res += bisect.bisect_right(pre, now - lower) - bisect.bisect_left(pre, now - upper)
bisect.insort(pre, now)
return res
class Solution:
def subarraysDivByK(self, nums: List[int], k: int) -> int:
dic = defaultdict(int)
dic[0] = 1
total,ans = 0,0
for i in nums:
total += i
num = total % k
ans += dic.get(num,0)
dic[num] += 1
return ans
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
dic = defaultdict(int)
dic[0] = 1
count,ans = 0, 0
for i in nums:
count += i
ans += dic.get(count - k,0)
dic[count] += 1
return ans
数组下标
思路:
nums=[4,3,2,4,1]
第一个值为4,将nums[3]变成负数,如果再次访问nums[3]还是负数,则重复出现
442.数组中的重复数据
287. 寻找重复数
之前还用的快慢指针 ,但是这个方法更简单
class Solution:
def findDuplicate(self, nums: List[int]) -> int:
for i in range(len(nums)):
if nums[abs(nums[i]) - 1] < 0:
return abs(nums[i])
nums[abs(nums[i]) - 1 ] = - nums[abs(nums[i]) - 1 ]
class Solution:
def firstMissingPositive(self, nums: List[int]) -> int:
N = len(nums)
for i in range(N):
if nums[i] <= 0:
nums[i] = N + 1
for i in range(N):
k = abs(nums[i]) - 1
if k < N and nums[k] > 0: #有标记不要重复添加
nums[k] = -nums[k]
for i in range(N):
if nums[i] > 0:
return i + 1
return N +1