leetcode学习笔记(4)——查找2

一、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


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值