leetcode刷题(4)

# 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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值