Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Leetcode问题&x27;3Sum';算法超出时间限制,正在寻求改进_Python_Python 3.x_Algorithm - Fatal编程技术网

Python Leetcode问题&x27;3Sum';算法超出时间限制,正在寻求改进

Python Leetcode问题&x27;3Sum';算法超出时间限制,正在寻求改进,python,python-3.x,algorithm,Python,Python 3.x,Algorithm,给定一个由n个整数组成的数组nums,nums中是否有元素a、b、c使得a+b+c=0?查找数组中所有唯一的三元组,该数组的和为零 class Solution: def threeSum(self, nums): data = [] i = j = k =0 length = len(nums) for i in range(length): for j in range(length):

给定一个由n个整数组成的数组nums,nums中是否有元素a、b、c使得a+b+c=0?查找数组中所有唯一的三元组,该数组的和为零

class Solution:
    def threeSum(self, nums):

        data = []
        i = j = k =0
        length = len(nums)
        for i in range(length):
            for j in range(length):
                if j == i:
                    continue
                for k in range(length):
                    if k == j or k == i:
                        continue
                    sorted_num = sorted([nums[i],nums[j],nums[k]])
                    if nums[i]+nums[j]+nums[k] == 0 and sorted_num not in data:
                        data.append(sorted_num)

        return data

我的溶液效果很好,但似乎太慢了。
有没有一种方法可以在不显著更改代码的情况下改进代码?

您的解决方案是蛮力方案,也是最慢的方案。 更好的解决方案可以是:

假设您从数组中的一个元素开始。考虑使用一个集合从剩余数组中查找下两个数字。< /P> 还有第三个更好的解决方案。请参见

这是一个带有一些优化技巧的O(n^2)解决方案:

import itertools

class Solution:
    def findsum(self, lookup: dict, target: int):
        for u in lookup:
            v = target - u
            # reduce duplication, we may enforce v <= u
            try:
                m = lookup[v]
                if u != v or m > 1:
                    yield u, v
            except KeyError:
                pass

    def threeSum(self, nums: List[int]) -> List[List[int]]:
        lookup = {}
        triplets = set()
        for x in nums:
            for y, z in self.findsum(lookup, -x):
                triplets.add(tuple(sorted([x, y, z])))
            lookup[x] = lookup.get(x, 0) + 1
        return [list(triplet) for triplet in triplets]
导入itertools
类解决方案:
def findsum(self,lookup:dict,target:int):
对于查找中的u:
v=目标-u
#减少重复,我们可以强制执行v 1:
产量u,v
除KeyError外:
通过
def threeSum(self,nums:List[int])->List[List[int]:
查找={}
三元组=集合()
对于NUM中的x:
对于self.findsum(查找,-x)中的y,z:
添加(元组(已排序([x,y,z]))
lookup[x]=lookup.get(x,0)+1
return[三元组中三元组的列表(三元组)]
首先,您需要一个散列查找来将O(n^3)算法减少到O(n^2)。这就是整个想法,其余都是微观优化:

  • 查找表是随阵列上的扫描一起生成的,因此它是一次扫描
  • 查找表索引以前看到的唯一项,因此它可以有效地处理重复项,通过使用它,我们可以将第二级循环的迭代次数保持在最小
    • 我建议:

      for j in range(i+1, length):
      
      这将为您节省len(nums)^2/2个步骤,并且第一个if语句变得多余

      sorted_num = sorted([nums[i],nums[j],nums[k]])
          if nums[i]+nums[j]+nums[k] == 0 and sorted_num not in data:
              sorted_num = sorted([nums[i],nums[j],nums[k]])
              data.append(sorted_num)
      

      为避免对最内层循环中排序的
      进行不必要的调用。

      这是一个优化版本,将通过以下步骤:

      from typing import List
      
      class Solution:
          def threeSum(self, nums: List[int]) -> List[List[int]]:
              unique_triplets = []
              nums.sort()
              for i in range(len(nums) - 2):
                  if i > 0 and nums[i] == nums[i - 1]:
                      continue
                  lo = i + 1
                  hi = len(nums) - 1
                  while lo < hi:
                      target_sum = nums[i] + nums[lo] + nums[hi]
                      if target_sum < 0:
                          lo += 1
                      if target_sum > 0:
                          hi -= 1
                      if target_sum == 0:
                          unique_triplets.append((nums[i], nums[lo], nums[hi]))
                          while lo < hi and nums[lo] == nums[lo + 1]:
                              lo += 1
                          while lo < hi and nums[hi] == nums[hi - 1]:
                              hi -= 1
                          lo += 1
                          hi -= 1
              return unique_triplets
      
      输入导入列表中的
      
      类解决方案:
      def threeSum(self,nums:List[int])->List[List[int]:
      唯一的_三联体=[]
      nums.sort()
      对于范围内的i(len(nums)-2):
      如果i>0且nums[i]==nums[i-1]:
      持续
      lo=i+1
      hi=len(nums)-1
      当lo0:
      hi-=1
      如果目标_sum==0:
      唯一的三元组。追加((nums[i],nums[lo],nums[hi]))
      而lo
      TLE最有可能适用于以下两种情况:

      • 而lo

      • 而lo


      工具书类
      • 有关更多详细信息,请参阅,您可以在其中找到大量解释良好的公认解决方案,包括低复杂度算法和渐近/分析

      您有i和j值。将所有内容存储在一个映射中并检查映射中是否存在(0-a-b),而不是再次迭代如何?如果您想要解决leetcode问题,请检查通道。这家伙解决了很多问题。否则,你可以打开讨论页面,在每个问题之后都可以使用该页面来优化解决方案。你的建议很容易理解,它帮助我加快了两倍,但仍然不够快,因为它仍然超过了时间限制。如果从list
      nums=list(set(nums)).sort()中删除重复的元素,我必须将O(n3)缩减为O(n2)。sort()
      ,我们可以避免三个额外的
      循环,使代码更短更清晰。