LeetCode 查找2

1 Two Sum

给出一个整型数组nums,返回这个数组中两个数字的索引值i和j,使得nums[i] + nums[j]等于一个给定的target值,两个索引不能相等。如:nums= [2,7,11,15],target=9,返回[0,1]

#暴力法,时间复杂度O(n^2)
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        len_nums = len(nums)
        for i in range(len_nums):
            for j in range(i+1,len_nums):
                if nums[i] + nums[j] == target:
                    return [i,j]
#排序+指针对撞(O(n)+O(nlogn)=O(n))
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        record = dict()
        nums_copy = nums.copy()
        sameFlag = True;
        nums.sort()
        l,r = 0,len(nums)-1
        while l < r:
            if nums[l] + nums[r] == target:
                break
            elif nums[l] + nums[r] < target:
                l += 1
            else:
                r -= 1
        res = []
        for i in range(len(nums)):
            if nums_copy[i] == nums[l] and sameFlag:
                res.append(i)
                sameFlag = False
            elif nums_copy[i] == nums[r]:
                res.append(i)
        return res

15 3Sum

给出一个整型数组,寻找其中的所有不同的三元组(a,b,c),使得a+b+c=0
注意:答案中不可以包含重复的三元组。
如:nums = [-1, 0, 1, 2, -1, -4],
结果为:[[-1, 0, 1],[-1, -1, 2]]

class Solution:
    def threeSum(self, nums: [int]) -> [[int]]:
        nums.sort()
        res = []
        for i in range(len(nums)-2):
            # 因为是排序好的数组,如果最小的都大于0可以直接排除
            if nums[i] > 0: break
            # 排除i的重复值
            if i > 0 and nums[i] == nums[i-1]: continue
            l,r = i+1, len(nums)-1
            while l < r:
                sum = nums[i] + nums[l] + nums[r]
                if sum == 0:
                    res.append([nums[i],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 sum < 0:
                    l += 1
                else:
                    r -= 1
        return res

16 3Sum Closest

给出一个整形数组,寻找其中的三个元素a,b,c,使得a+b+c的值最接近另外一个给定的数字target。
给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).

class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        nums.sort()
        diff = abs(nums[0]+nums[1]+nums[2]-target)
        res = nums[0] + nums[1] + nums[2]
        for i in range(len(nums)):
            l,r = i+1,len(nums)-1
            t = target - nums[i]
            while l < r:
                if nums[l] + nums[r] == t:
                    return nums[i] + t
                else:
                    if abs(nums[l]+nums[r]-t) < diff:
                        diff = abs(nums[l]+nums[r]-t)
                        res = nums[i]+nums[l]+nums[r]
                    if nums[l]+nums[r] < t:
                        l += 1
                    else:
                        r -= 1
        return res

18 4Sum

给出一个整形数组,寻找其中的所有不同的四元组(a,b,c,d),使得a+b+c+d等于一个给定的数字target。

class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        result = []
        res = {}
        if not nums or len(nums) < 4:
            return result
        nums.sort()
        for k in range(len(nums)-3):
            target1 = target-nums[k]
            if len(nums)-k>=4:
                for i in range(k+1,len(nums)):
                    # if i > 0 and nums[i-1]==nums[i]:
                    #     continue 
                    d = {}
                    target2 = target1 -nums[i]
                    if len(nums)-i>=3:
                        for j in range(i+1,len(nums)):
                            if target2 - nums[j] in d:
                                item = [nums[k],nums[i],nums[j],target2-nums[j]]
                                item.sort()
                                key = ''.join([str(x) for x in item ])
                                if key not in res:
                                    result.append(item)
                                    res[key] = 1
                            d[nums[j]] = j
        return result

49 Group Anagrams

给出一个字符串数组,将其中所有可以通过颠倒字符顺序产生相同结果的单词进行分组。
示例:
输入: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],
输出:[[“ate”,“eat”,“tea”],[“nat”,“tan”],[“bat”]]
说明:
所有输入均为小写字母。
不考虑答案输出的顺序。

class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        dic = {} #
        res = []
        for word in strs:
            dic.setdefault(str(sorted(word)),[]).append(word)
        for val in dic.values():
            res.append(val)
        return res

149 Max Points on a Line

给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上。
输入: [[1,1],[2,2],[3,3]]
输出: 3

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])

447 Number of Boomerangs

给出一个平面上的n个点,寻找存在多少个由这些点构成的三元组(i,j,k),使得i,j两点的距离等于i,k两点的距离。其中n最多为500,且所有的点坐标的范围在[-10000,10000]之间。
输入:[[0,0],[1,0],[2,0]]
输出:2
解释:
两个结果为: [[1,0],[0,0],[2,0]] 和 [[1,0],[2,0],[0,0]]

class Solution:
    def numberOfBoomerangs(self, points: List[List[int]]) -> int:
        result = 0
        for s in points:
            d = {}
            for t in points:
                l = (s[0]-t[0])**2+(s[1]-t[1])**2
                if l in d:
                    d[l] += 1
                else:
                    d[l] = 1
            for k in d:
                result += d[k]*(d[k]-1)
        return result

454 4SumⅡ

给出四个整形数组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;
输入:
A = [ 1, 2] B = [-2,-1] C = [-1, 2] D = [ 0, 2]
输出:2

class Solution:
    def fourSumCount(self, A: List[int], B: List[int], C: List[int], D: List[int]) -> int:
        dic = collections.Counter(a + b for a in A for b in B)
        return sum(dic.get(- c - d, 0) for c in C for d in D)

219 Contains Dupliccate Ⅱ

==给出一个整形数组nums和一个整数k,是否存在索引i和j,使得nums[i]nums[j],且i和J之间的差不超过k。
示例1:
输入: nums = [1,2,3,1], k = 3
输出: true

class Solution:
    def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
        d = {}
        for index,n in enumerate(nums):
            d.setdefault(n,[]).append(index)
        for poses in d.values():
            if len(poses)<=1: pass
            for i in range(len(poses)-1):
                if poses[i+1]-poses[i] <= k: return True
        return False

220 Contains Dupliccate Ⅲ

给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得nums [i] 和nums [j]的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ。
输入: nums = [1,2,3,1], k = 3, t = 0
输出: true

class Solution:
    def containsNearbyAlmostDuplicate(self, nums, k, t) -> bool:
        record = set()
        for i in range(len(nums)):
            if len(record) != 0:
                rec = list(record)
                find_index = self.lower_bound(rec,nums[i]-t)
                if find_index != -1 and rec[find_index] <= nums[i] + t:
                    return True
            record.add(nums[i])
            if len(record) == k + 1:
                record.remove(nums[i - k])
        return False
    def lower_bound(self, nums, target):
        low, high = 0, len(nums)-1
        while low<high:
            mid = int((low+high)/2)
            if nums[mid] < target:
                low = mid+1
            else:
                high = mid
        return low if nums[low] >= target else -1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值