在没有两个相邻数字相同的情况下,如何计算n个数字的序列数?

时间:2019-05-07 21:04:11

标签: python

免责声明:我是python / coding的新手,所以对于某些专家来说,这可能太基础了。

我需要优化解决以下问题的解决方案:找到n个数字的序列数,其中序列中没有两个相邻的数字相同,并且序列中的值可以是1到k之间的任何数字(k可以是小于或大于n)。

我试图通过一种蛮力的方法来找到这个问题,首先找到序列,然后对它们进行计数,但是解决方案显然没有优化,因此出现了内存问题。

以下是使用python中的itertools库的代码:


def notsame(nums): 
    return all(num1 != num2 for num1, num2 in zip(nums, nums[1:])) 
def sequence_count(n, k):
    count = 0
    a = list(range(1, k+1))
    for item in list(it.product(a, repeat = n)):
        if notsame(list(item)):
           count += 1
#taking the modulo as the number of sequences could get really large.
   count = count % (10**10+7)   
   print(count) 

例如,如果我们给定n = 3且k = 2的值,则符合所需标准的可能序列为(1、2、1),(2、1、2),因此计数为2

2 个答案:

答案 0 :(得分:2)

这是一个封闭形式的解决方案,与列出所有可能性相比,计算可能性的数量要容易得多,因此,这比编码问题更像是计数问题。

我们将计算每个位置n的可能性,然后将它们相乘。

在示例中,您给出了n = 3,然后k = 2

  • 第一个位置有2个选项(1或2)
  • 第二位置只有1个选项(不能与位置1的位置相同)
  • 第3个位置也只有1个选项(不能与pos 2相同)

所以当n = 3时的公式是:

k *(k-1)*(k-1)= 2,当k = 2

我们可以将其概括为: counts = k*(k-1)**(n-1)

如果您确实需要列出所有可能性而不仅仅是计算,那么这个答案是不够的

答案 1 :(得分:1)

如果您坚持要计数,并且可能需要结果, 递归可能会有所帮助。

def ap(n, k):
    if n==1:
        for e in range(k):
            yield [e + 1]
    else:
        for e in range(k):
            for e2 in ap(n - 1, k):
                tmp = [e + 1] + e2
                for i in range(len(tmp) - 1):
                    if tmp[i] == tmp[i + 1]:
                        break
                else:        
                    yield tmp

# count    
print(sum(1 for v in ap(4, 3)))
# result
print(list(ap(4, 3)))

这比您的记忆方式要好一些,但仍然非常慢。