【问题标题】:Overcome TLE (Time Limit Exceeded) Error for python code克服python代码的TLE(超过时间限制)错误
【发布时间】:2021-08-28 03:44:19
【问题描述】:

我在 GeeksforGeeks 上尝试过提交时出现 TLE 错误的代码。

问题来了:
Geek 得到一个长度为 nnums 数组和两个整数 xy。极客有兴趣找到满足 x 帮助极客找出此类配对的总数。

示例 1:

Input: nums[] = {5,3,7,9,7,9,7,7},                                                                
x = 7, y = 19  
Output: 1   
Explanation: There is only one pair which
satisfies the given conditions. The pair is
(1,2).

示例 2:

Input: nums[] = {3,5,5,2,6},                                   
x = 8, y = 13                                                                          
Output: 3  
Explanation: Pairs which satisfiy the given
conditions are (2,4), (3,4), (4,5).

约束:

1<=n<=10^4   
1<=nums[i]<=10^4      
1<=x<=y<=10^8

这是我的代码:

class Solution:
    def TotalPairs(self, nums, x, y):
        count = 0
        for i in range(len(nums)):
            for j in range(i+1, len(nums)):
                if x <= nums[i]*nums[j] <= y:
                    count += 1
        return count


#{ 
#  Driver Code Starts
if __name__ == '__main__':
    T=int(input())
    for i in range(T):
        n, x, y = map(int, input().split())
        nums = list(map(int, input().split()))
        obj = Solution()
        ans = obj.TotalPairs(nums, x, y)
        print(ans)
# } Driver Code Ends

提交后的输出:
运行时错误:
超出运行时错误时间限制

您的程序花费的时间比预期的要长。
预计时间限制 7.60 秒
提示:请优化您的代码并再次提交。

【问题讨论】:

  • 跟随提示!
  • 这就是本练习的重点——使用更高效的算法编写代码
  • 尝试在 GeeksforGeeks 上搜索相同的问题。可能会有一篇文章解释如何优化它。

标签: python python-3.8


【解决方案1】:

通过使用组合,我们可以将 O(n^2) 减少到 O(n)。试试这个:

from itertools import combinations
import math
class Solution:
    def TotalPairs(self, nums, x, y):
        count = 0
        _x = [a[0] * a[1] for a in list(combinations(nums, 2))]
        for i in _x:
            if x <= i <= y:
                count += 1
        return count

编辑:您也可以使用lru_cache 来减少执行时间

from itertools import combinations
import math
from functools import lru_cache
import functools
import time
class Solution:
    def ignore_unhashable(func): 
        uncached = func.__wrapped__
        attributes = functools.WRAPPER_ASSIGNMENTS + ('cache_info', 'cache_clear')
        @functools.wraps(func, assigned=attributes) 
        def wrapper(*args, **kwargs): 
            try: 
                return func(*args, **kwargs) 
            except TypeError as error: 
                if 'unhashable type' in str(error): 
                    return uncached(*args, **kwargs) 
                raise 
        wrapper.__uncached__ = uncached
        return wrapper
    @ignore_unhashable
    @lru_cache(maxsize = 128)
    def TotalPairs(self, nums, x, y):
        count = 0
        _x = [a[0] * a[1] for a in list(combinations(nums, 2))]
        for i in _x:
            if x <= i <= y:
                count += 1
        return count

【讨论】:

  • 并非如此。这里组合本身的复杂性是 N 选择 2,所以它仍然是 N^2 解决方案。
  • 嗯……确实
  • 在下面写了一个 NlogN 解决方案的想法。
【解决方案2】:

你有一个 O(N^2) 的解决方案。

这就是我认为您可以做的事情,而无需尝试放弃大部分代码,因为这毕竟是一个练习。

基本上,对于数组中的每个数字num
您需要找出数组中有多少个数字在[ceil(x/num), floor(y/num)] 范围内。

举个例子,如果 x = 7 和 y = 19,并且说 num = 2。
那么满足条件的最小产品是8,也就是num * ceil(x/num) = 2 * ceil(7/2) = 4
最大乘积同样为 18,即num * floor(y/num) = 2 * floor(19/2) = 18
因此,对于 2,您需要列表中位于 [4, 9] 范围内的数字。

这是否暗示了你应该做什么?

您首先对数组进行排序。
然后对于每个数字:
1)你找到ceil(x/num)和floor(y/num)的索引,使用二分查找
2)对的数量将是两个索引的差+ 1。

这样做的复杂性是,你需要 O(NlogN) 时间来排序,然后你遍历所有需要 O(N) 时间的数字,对于每个数字你执行两个二进制搜索操作,所以这是 @ 987654325@

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多