一、Task04:查找2
1.1 独立完成以下leetcode题目:
1. 两数之和
15. 三数之和
16. 最接近的三数之和
18. 四数之和
49. 字母异位词分组
149. 直线上最多的点数
219. 存在重复元素 II
220. 存在重复元素 III
447. 回旋镖的数量
454. 四数相加 II
二、代码
这次组队学习的最后一次交作业了!
2.1代码——两数之和
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
l=len(nums)
if not l:
return []
nums,ind=zip(*sorted(zip(nums,list(range(l)))))
i=0
j=l-1
while i<j:
if nums[i]+nums[j]==target:
return [ind[i],ind[j]]
elif nums[i]+nums[j]>target:
j-=1
else:
i+=1
return []
2.2代码——三数之和
class Solution:
def threeSum(self, nums: [int]) -> [[int]]:
nums.sort()
res, k = [], 0
for k in range(len(nums) - 2):
if nums[k] > 0: break # 1. because of j > i > k.
if k > 0 and nums[k] == nums[k - 1]: continue # 2. skip the same `nums[k]`.
i, j = k + 1, len(nums) - 1
while i < j: # 3. double pointer
s = nums[k] + nums[i] + nums[j]
if s < 0:
i += 1
while i < j and nums[i] == nums[i - 1]: i += 1
elif s > 0:
j -= 1
while i < j and nums[j] == nums[j + 1]: j -= 1
else:
res.append([nums[k], nums[i], nums[j]])
i += 1
j -= 1
while i < j and nums[i] == nums[i - 1]: i += 1
while i < j and nums[j] == nums[j + 1]: j -= 1
return res
2.代码——最接近的三数之和
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
redsult = []
nums.sort()
tmp = nums[0] + nums[1] + nums[2]
res = abs(nums[0] + nums[1] + nums[2] - target)
for i in range(len(nums)):
if i > 0 and nums[i] == nums[i - 1]:
continue
left, right = i + 1, len(nums) - 1
while left < right:
currSum = nums[i] + nums[left] + nums[right]
if currSum == target:
return currSum
else:
if abs(currSum - target) < res:
res = abs(currSum - target)
tmp = currSum
if currSum < target:
left += 1
else:
right -= 1
return tmp
2.代码——四数之和
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
if len(nums) < 4: return []
nums.sort()
result = []
for idx in range(len(nums) - 3):
if nums[idx] + nums[idx+1] * 3 > target: break
if idx > 0 and nums[idx] == nums[idx - 1]: continue
if nums[idx] + nums[-1] * 3 < target: continue
for i in range(idx+1, len(nums)-2):
if nums[idx] + nums[i] + nums[i + 1] * 2 > target: break
if nums[idx] + nums[i] + nums[-1] * 2 < target: continue
if i > idx+1 and nums[i] == nums[i-1]: continue
j, k = i + 1, len(nums) - 1
while j < k:
s = nums[idx] + nums[i] + nums[j] + nums[k]
if s > target:
k -= 1
elif s < target:
j += 1
else:
result.append([nums[idx], nums[i], nums[j], nums[k]])
while j < k and nums[j] == nums[j + 1]: j += 1
while j < k and nums[k] == nums[k - 1]: k -= 1
j += 1
k -= 1
return result
2.代码——字母异位词分组
class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
d = {}
for s in strs:
key = tuple(sorted(s))
d[key] = d.get(key, []) + [s]
return list(d.values())
2.代码——直线上最多的点数
from collections import Counter
class Solution:
def maxPoints(self, points: List[List[int]]) -> int:
def K(i,j):
return float('Inf') if i[1] - j[1] == 0 else (i[0] - j[0]) / (i[1] - j[1])
if len(points) <= 2:
return len(points)
maxans = 0
for i in points:
same = sum(1 for j in points if j == i)
hashmap = Counter([K(i,j) for j in points if j != i])
tempmax = hashmap.most_common(1)[0][1] if hashmap else 0
maxans = max(same + tempmax, maxans)
return maxans
2.代码——存在重复元素 II
class Solution:
def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
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
2.代码——存在重复元素 III
class Solution:
def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:
bucket = dict()
if t < 0: return False
for i in range(len(nums)):
nth = nums[i] // (t + 1)
if nth in bucket:
return True
if nth - 1 in bucket and abs(nums[i] - bucket[nth - 1]) <= t:
return True
if nth + 1 in bucket and abs(nums[i] - bucket[nth + 1]) <= t:
return True
bucket[nth] = nums[i]
if i >= k: bucket.pop(nums[i - k] // (t + 1))
return False
2.代码——回旋镖的数量
class Solution:
def numberOfBoomerangs(self, points: List[List[int]]) -> int:
res=0
for i in points:
dicts={}
for j in points:
if i==j:
continue
dicts[(i[0]-j[0])**2+(i[1]-j[1])**2]=dicts.get((i[0]-j[0])**2+(i[1]-j[1])**2,0)+1
for i in dicts.values():
res+=i*(i-1)
return res
2.代码——四数相加 II
import collections
class Solution:
def fourSumCount(self, A: List[int], B: List[int], C: List[int], D: List[int]) -> int:
A = collections.Counter(A)
B = collections.Counter(B)
C = collections.Counter(C)
D = collections.Counter(D)
AB = {}
for ka in A:
for kb in B:
kab = ka + kb
if kab not in AB:
AB[kab] = A[ka]*B[kb]
else:
AB[kab] += A[ka]*B[kb]
result = 0
for kc in C:
for kd in D:
kab = - kc - kd
if AB.get(kab):
# 已经记过数,用乘法
result += C[kc]*D[kd]*AB[kab]
return result