# 1. 两数之和 利用字典 哈希查找
class Solution1:
def twoSum(self,nums,target):
d = {}
n = len(nums)
for x in range(n):
if target - nums[x] in d:
return d[target-nums[x]],x
else:
d[nums[x]] = x
# 15 三数之和。 排序 双指针
class Solution2:
def threeSum(self,nums):
n = len(nums)
nums.sort()
ans = list()
# 枚举 a
for first in range(n):
# 需要和上一次枚举的数不相同
if first > 0 and nums[first] == nums[first - 1]:
continue
# c 对应的指针初始指向数组的最右端
third = n - 1
target = -nums[first]
# 枚举 b
for second in range(first + 1, n):
# 需要和上一次枚举的数不相同
if second > first + 1 and nums[second] == nums[second - 1]:
continue
# 需要保证 b 的指针在 c 的指针的左侧
while second < third and nums[second] + nums[third] > target:
third -= 1
# 如果指针重合,随着 b 后续的增加
# 就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环
if second == third:
break
if nums[second] + nums[third] == target:
ans.append([nums[first], nums[second], nums[third]])
return ans
# 16 最接近三数之和。 排序 双指针
class Solution3:
def threeSumClosest(self, nums, target):
nums.sort()
n = len(nums)
best = 10 ** 7
# 根据差值的绝对值来更新答案
def update(cur):
nonlocal best
if abs(cur - target) < abs(best - target):
best = cur
# 枚举 a
for i in range(n):
# 保证和上一次枚举的元素不相等
if i > 0 and nums[i] == nums[i - 1]:
continue
# 使用双指针枚举 b 和 c
j, k = i + 1, n - 1
while j < k:
s = nums[i] + nums[j] + nums[k]
# 如果和为 target 直接返回答案
if s == target:
return target
update(s)
if s > target:
# 如果和大于 target,移动 c 对应的指针
k0 = k - 1
# 移动到下一个不相等的元素
while j < k0 and nums[k0] == nums[k]:
k0 -= 1
k = k0
else:
# 如果和小于 target,移动 b 对应的指针
j0 = j + 1
# 移动到下一个不相等的元素
while j0 < k and nums[j0] == nums[j]:
j0 += 1
j = j0
return best
# 18 四数之和
class Solution4:
def fourSum(self, nums, target):
nums.sort()
res = []
if len(nums) < 4:
return res
n = len(nums)
for first in range(n - 3):
if first > 0 and nums[first] == nums[first - 1]:
continue # 去掉重复的个元素
for second in range(first + 1, n - 2):
if second > first + 1 and nums[second] == nums[second - 1]:
continue
third, fourth = second + 1, n - 1
while third < fourth:
if nums[first] + nums[second] + nums[third] + nums[fourth] < target:
third += 1
elif nums[first] + nums[second] + nums[third] + nums[fourth] > target:
fourth -= 1
else:
res.append([nums[first], nums[second], nums[third], nums[fourth]])
while third < fourth and nums[third] == nums[third + 1]:
third += 1
while third < fourth and nums[fourth] == nums[fourth - 1]:
fourth -= 1
third += 1
fourth -= 1
return res
# 49 字母异位表
import collections
class Solution5:
def groupAnagrams(self, strs):
ans = collections.defaultdict(list)
for s in strs:
ans[tuple(sorted(s))].append(s)
return ans.values()
# 149 直线上最多的点数
class Solution6(object):
def groupAnagrams(self, strs):
ans = collections.defaultdict(list)
for s in strs:
ans[tuple(sorted(s))].append(s)
return ans.values()
from collections import *
class Solution7:
def maxPoints(self, points):
# i是需要判断点的索引
def calc(points, i):
# defaultdict是collections里的一个类,就是带有默认值的字典
# 这样不用在给字典赋值时先判断key存不存在了
hashmap = defaultdict(int)
# 记录与需要判断点重合点的数目
same = 0
for j in range(len(points)):
# 不对同一个点进行计算
if j != i:
# 如果两点坐标相同same加一然后跳回循环开始
if points[i] == points[j]:
same += 1
continue
# 因为可能存在斜率无穷大的情况,提前做判断
if points[i][1] - points[j][1] == 0:
k = float('Inf')
else:
k = (points[i][0] - points[j][0]) / (points[i][1] - points[j][1])
# 最后更新hashmap
hashmap[k] += 1
# 取hashmap中最大值加上重复的个数再加一就是该点的结果
return 1 + same + (max(hashmap.values()) if hashmap else 0)
res = 0
if len(points) == 1: return 1
# 对于每个点进行一次calc操作,取最大值作为答案
for i in range(len(points)):
res = max(res, calc(points, i))
return res
# 219 查找相同元素 哈希查找
class Solution8:
def containsNearbyDuplicate(self, nums, k: int) :
dict = {}
for i in range(len(nums)):
if nums[i] in dict and i - dict[nums[i]] <= k:
return True
dict[nums[i]] = i
return False
# 220 哈希查找。查找相同元素3
class Solution9:
def containsNearbyAlmostDuplicate(self, nums, k: int, t):
if t < 0 or not k or not nums:
return False
if k == 1:
for i in range(len(nums)-1):
if abs(nums[i]-nums[i+1]) <= t:
return True
return False
if not t:
dct = {}
for inx, i in enumerate(nums):
if i in dct:
if inx-dct[i] <= k:
return True
dct[i] = inx
return False
lst = []
i = nums[0]
lst.append(sum([(i-j, i+j) for j in range(t+1)], ()))
for i in nums[1:]:
if i in set(sum(lst, ())):
return True
lst.append(sum([(i-j, i+j) for j in range(t+1)], ()))
lst = lst[-k:]
return False
# 447回旋镖数量 遍历点点组合,统计距离到某点相等的数量,然后根据组合公式求解子和,
class Solution10:
def numberOfBoomerangs(self, points) -> int:
def f(x1, y1):
d = collections.Counter((x2 - x1) ** 2 + (y2 - y1) ** 2 for x2, y2 in points)
return sum(t * t - t for t in d.values())
return sum(f(x1, y1) for x1, y1 in points)
# 454 四数和
class Solution11:
def fourSumCount(self, A, B, C, D):
absum_count = dict() # 记录A、B中元素的和的出现的次数,
count = 0
for a in A:
for b in B:
absum_count[a + b] = absum_count.get(a + b, 0) + 1
for c in C:
for d in D:
cdsum = c + d
if -cdsum in absum_count: # 如果c、d的和的相反数在ab_sum中出现,则加上对应的次数
count += absum_count[-cdsum]
return count
#遍历前两个数组可以相加得到所有值的个数,然后再遍历后两个数组。
class Solution12:
def fourSumCount(self, A, B, C, D) -> int:
lookup = collections.defaultdict(int)
res = 0
for a in A:
for b in B:
lookup[a + b] += 1
for c in C:
for d in D:
res += lookup[-(c + d)]
return res
leetcode刷题(4)
最新推荐文章于 2023-05-28 22:18:53 发布