微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

回溯解决方案的大O计算范围内的排列

如何解决回溯解决方案的大O计算范围内的排列

我有一个问题,我一直在努力解决解决方案的时间和空间的复杂性:

给出一个整数数组(可能重复)Aminlowhigh是整数。 在A中找到以下项的组合总数:

  • low <= A[i] <= high
  • 每个组合至少具有min个数字。
  • 一个组合中的数字可以重复,因为它们在A中被认为是唯一的,但是组合不能重复。例如:[1,1,2]->组合:[1,1],[1,2],2]可以,但[1,[2,1] ...不能。

示例:A=[4,6,3,13,5,10],min = 2,low = 3,high = 5

有四种方法可以在A中组合有效的整数:[4,3],[4,5],[3,5]

这是我的解决方案,它有效:

class Solution:
    def __init__(self):
        pass
    def get_result(self,arr,min_size,low,high):
        return self._count_ways(arr,high,0)
    def _count_ways(self,idx,comb_size):
        if idx == len(arr):
            return 0
        count = 0
        for i in range(idx,len(arr)):
            if arr[i] >= low and arr[i] <= high:
                comb_size += 1
                if comb_size >= min_size:
                    count += 1
                count += self._count_ways(arr,i + 1,comb_size)
                comb_size -= 1
        return count

我使用回溯,所以:

时间:O(n!),因为在最坏的情况下-当所有整数都可以形成组合时,我会检查每一个整数是否剩余。

空格:O(n)最多只能在调用堆栈上进行n次调用,并且我仅使用2个变量来跟踪我的组合。

我的分析正确吗?

也有点超出范围,但是:我是否应该做一些记忆来改善它?

解决方法

如果我正确理解您的要求,则您的算法太复杂了。您可以按照以下步骤进行操作:

  1. 计算数组B,其中包含Alow之间的high中的所有元素。
  2. sum of Choose(B.length,k)返回k = min .. B.length,其中Choose(n,k)n(n-1)..(n-k+1)/k!

如果您使用备忘录来计算O(n)函数的分子/分母,则时间和空间的复杂度为Choose(例如,如果您已经计算了5*4*3,则只需乘以计算5*4*3*2等。

在您的示例中,您将得到B = [4,3,5],因此B.length = 3,结果是

  Choose(3,2) + Choose(3,3) 
= (3 * 2)/(2 * 1) + (3 * 2 * 1)/(3 * 2 * 1) 
= 3 + 1
= 4
,

您对时间复杂度的分析不太正确。

我了解您在哪里获得O(n!):每次进行递归调用时,for i in range(idx,len(arr)):循环的长度都会减少,因此好像您在进行n*(n-1)*(n-2)*...

但是,长度为m的循环的递归调用并不总是包含大小为m-1的循环。假设您最外面的电话有3个元素。循环迭代3个可能的值,每个值都产生一个新的调用。第一个这样的调用将具有一个循环,该循环迭代2个值,但是下一个调用仅迭代1个值,而最后一个立即击中您的基本情况并停止。因此,您得到的是3*2*1=((1+1)+(1+1)+(1+1)),而不是((1+0)+1+0)

对大小为_count_ways的数组n的调用所花费的时间是大小为n-1的调用的两倍。要看到这一点,请考虑调用大小为n的第一个分支,该分支是否选择第一个元素。首先,我们选择第一个元素,这导致大小为n-1的递归调用。其次,我们不选择第一个元素,它使我们n-1个元素可以迭代,因此好像我们有第二个递归调用,大小为n-1

n的每次增加都会使时间复杂度增加2倍,因此解决方案的时间复杂度为O(2^n)。这很有意义:您正在检查每个组合,并且2^n个组合的大小为n

但是,由于您仅尝试计算组合而不对组合进行任何操作,因此效率非常低。有关更好的解决方案,请参见@Mo B.的答案。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。