-
题目
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。 -
代码
-
解法一:暴力法,时间复杂度为(O(n^2))
class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: for i in range(len(nums)): for j in range(i+1,len(nums)): if nums[i] + nums[j] == target: return [i,j]
-
解法二:查找表,遍历数组到元素v时,查看查找表中是否有target-v,若无则将该元素v放入查找表继续遍历。时间复杂度和空间复杂度均为(O(n))
# 注意:前提条件,数组元素不能重复。 class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: search_dic = {} for i in range(len(nums)): v = target-nums[i] if search_dic.get(v,None) is None: search_dic[nums[i]] = i else: return [i,search_dic[v]]
-
解法三:对撞指针,先保存list中各元素的索引值,然后对list进行排序,前后对撞指针返回
class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: nums = list(enumerate(nums)) nums.sort(key=lambda x:x[1]) l,r = 0,len(nums)-1 while l < r: if nums[l][1] + nums[r][1] < target: l += 1 elif nums[l][1] + nums[r][1] > target: r -= 1 else: return nums[l][0],nums[r][0]
-
-
题目
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。 -
代码
排序+对撞指针。class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: nums_len = len(nums) if nums_len < 3: return [] res_ls = [] nums.sort() for i in range(nums_len): if nums[i] > 0: break if i > 0 and nums[i] == nums[i-1]: continue l,r = i+1,nums_len-1 while l<r: if nums[i] + nums[l] + nums[r] == 0: res_ls.append([nums[i],nums[l],nums[r]]) l += 1 r -= 1 while l<r and nums[l-1] == nums[l]: l += 1 while l<r and nums[r] == nums[r+1]: r -= 1 elif nums[i] + nums[l] + nums[r] > 0: r -= 1 else: l += 1 return res_ls
-
题目
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
-
代码
class Solution: def threeSumClosest(self, nums: List[int], target: int) -> int: res_sum = sum(nums[:3]) min_sub = abs(res_sum-target) nums.sort() for i in range(len(nums)): l,r = i+1, len(nums)-1 while l<r: if nums[i] + nums[l] + nums[r] == target: return target else: if abs(nums[i] + nums[l] + nums[r]-target) < min_sub: res_sum = nums[i] + nums[l] + nums[r] min_sub = abs(res_sum-target) if nums[i] + nums[l] + nums[r] < target: l += 1 else: r -= 1 return res_sum
-
题目
给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。
注意:答案中不可以包含重复的四元组。 -
代码
class Solution: def fourSum(self, nums: List[int], target: int) -> List[List[int]]: nums.sort() res_ls = [] nums_len = len(nums) if nums_len < 4: return res_ls if nums_len == 4: if sum(nums) == target: res_ls.append(nums) return res_ls for i in range(nums_len-3): if i > 0 and nums[i-1]==nums[i]: continue for j in range(i+1,nums_len-2): if j > i + 1 and nums[j-1]==nums[j]: continue l,r = j+1,nums_len-1 while l<r: if nums[i] + nums[j] + nums[l] + nums[r] == target: res_ls.append([nums[i],nums[j],nums[l],nums[r]]) l += 1 r -= 1 while l<r and nums[l] == nums[l-1]: l+=1 while l<r and nums[r] == nums[r+1]: r-=1 elif nums[i] + nums[j] + nums[l] + nums[r] < target: l += 1 else: r -= 1 return res_ls
-
题目
给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
-
代码
class Solution: def groupAnagrams(self, strs: List[str]) -> List[List[str]]: from collections import defaultdict strs_dic = defaultdict(list) for stro in strs: key = ''.join(sorted(list(stro))) strs_dic[key] += stro.split(',') return [v for v in strs_dic.values()]
-
题目
给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上。
-
代码
class Solution: def maxPoints(self,points): if len(points) <= 1: return len(points) res = 0 from collections import defaultdict for i in range(len(points)): record = defaultdict(int) samepoint = 0 for j in range(len(points)): if points[i][0] == points[j][0] and points[i][1] == points[j][1]: samepoint += 1 else: record[self.get_Slope(points,i,j)] += 1 for v in record.values(): res = max(res, v+samepoint) res = max(res, samepoint) return res def get_Slope(self,points,i,j): if points[i][1] - points[j][1] == 0: return float('Inf') else: return (points[i][0] - points[j][0]) / (points[i][1] - points[j][1])
-
题目
给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的 绝对值 至多为 k。
-
代码
class Solution: def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool: nums_set = set() for i in range(len(nums)): if nums[i] in nums_set: return True nums_set.add(nums[i]) if len(nums_set)==k+1: nums_set.remove(nums[i-k]) return False
-
题目
在整数数组 nums 中,是否存在两个下标 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值小于等于 t ,且满足 i 和 j 的差的绝对值也小于等于 ķ 。
如果存在则返回 true,不存在返回 false。 -
代码
-
解法一:二分查找,缺点:耗时太长
class Solution: def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool: def checkin(dset, d): dlist = list(dset) dlist.sort() l,r=0,len(dlist)-1 while l<=r: mid = (l+r) //2 if abs(d-dlist[mid])<=t: return True elif d-dlist[mid] < 0: r = mid-1 else: l = mid+1 return False res_set = set() for i in range(len(nums)): if checkin(res_set,nums[i]): return True res_set.add(nums[i]) if len(res_set) == k+1: res_set.remove(nums[i-k]) return False
-
解法二:暴力法
class Solution: def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool: if t==0: if len(nums) == len(set(nums)): return False else: return True for i in range(len(nums)): for j in range(i+1,i+1+k): if j >= len(nums): break if abs(nums[i]-nums[j]) <= t: return True return False
-
-
题目
给定平面上 n 对不同的点,“回旋镖” 是由点表示的元组 (i, j, k) ,其中 i 和 j 之间的距离和 i 和 k 之间的距离相等(需要考虑元组的顺序)。
找到所有回旋镖的数量。你可以假设 n 最大为 500,所有点的坐标在闭区间 [-10000, 10000] 中。 -
代码
class Solution: def numberOfBoomerangs(self, points: List[List[int]]) -> int: from collections import Counter def f(x1,y1): point_dic = Counter((x2-x1)**2+(y2-y1)**2 for x2,y2 in points) return sum(t*(t-1) for t in point_dic.values()) return sum(f(x,y) for x,y in points)
-
题目
给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。
为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500 。所有整数的范围在 (-2^{28}) 到 (2^{28}-1) 之间,最终结果不会超过 (2^{31}-1) 。 -
代码
-
解法一:(O(n^3)) 无法通过,超出限制
class Solution: def fourSumCount(self, A: List[int], B: List[int], C: List[int], D: List[int]) -> int: from collections import Counter search_dic = Counter(D) res = 0 for i in range(len(A)): for j in range(len(B)): for k in range(len(C)): if 0-(A[i]+B[j]+C[k]) in search_dic: res += search_dic[0-(A[i]+B[j]+C[k])] return res
-
解法二:(O(n^2))
class Solution: def fourSumCount(self, A: List[int], B: List[int], C: List[int], D: List[int]) -> int: from collections import Counter search_dic = Counter() for i in range(len(C)): for j in range(len(D)): search_dic[C[i]+D[j]] += 1 res = 0 for i in range(len(A)): for j in range(len(B)): find_value = 0-(A[i]+B[j]) if find_value in search_dic: res += search_dic[find_value] return res
-
解法三:优化
class Solution: def fourSumCount(self, A: List[int], B: List[int], C: List[int], D: List[int]) -> int: from collections import Counter search_dic = Counter(c+d for c in C for d in D) return sum(search_dic.get(-a-b,0) for a in A for b in B)
-