zoukankan      html  css  js  c++  java
  • 查找2 | Leetcode分类练习 | Datawhale- 打卡(四)

    1. 两数之和

    • 题目

      给定一个整数数组 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]
        

    15. 三数之和

    • 题目

      给你一个包含 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
      

    16. 最接近的三数之和

    • 题目

      给定一个包括 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
      

    18. 四数之和

    • 题目

      给定一个包含 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   
      

    49. 字母异位词分组

    • 题目

      给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。

    • 代码

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

    149. 直线上最多的点数

    • 题目

      给定一个二维平面,平面上有 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])
      

    219. 存在重复元素 II

    • 题目

      给定一个整数数组和一个整数 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
      

    220. 存在重复元素 III

    • 题目

      在整数数组 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
        

    447. 回旋镖的数量

    • 题目

      给定平面上 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)
      

    454. 四数相加 II

    • 题目

      给定四个包含整数的数组列表 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)
        

  • 相关阅读:
    redis集群报错,(error) MOVED 15495 127.0.0.1:7003
    在云服务器上时候,我关闭了防火墙还是不能连接!
    redis 集群安装 3主3从3台云主机
    ajax完成团队信息异步添加【实际项目】
    众创项目首页推荐需求
    添加删除表格(js完成)【自己实际项目】
    【JPA 级联保存/级联删除】@OneToMany (双向) 一对多【转】
    页面提交 string数组和list对象集合举例
    Form表单如何传递List数组对象到后台的解决办法(转)
    实现同时提交多个form(基础方法) 收集(转)
  • 原文地址:https://www.cnblogs.com/rn-05181226-rw/p/13563175.html
Copyright © 2011-2022 走看看