《数组子序列的排列数量》 | 豆包MarsCode AI刷题

37 阅读2分钟

想象一下,小 R 就像一个充满好奇心的探险家,他手里拿着一个长度为 n 的神秘数组。这个数组里装着各种各样的数字,就像是一个装满宝藏的宝箱。小 R 呢,他突发奇想,想要在这个数组里寻找一种特殊的宝藏 —— 子序列排列。

那什么是子序列呢?简单来说,子序列就像是从这个宝箱里挑出一部分宝藏。你可以挑很多,也可以只挑一两个,甚至一个都不挑(当然,这种情况就没什么意思啦)。从原数组里删掉一些元素,或者干脆不删,留下来的那部分就是子序列。

而排列这个概念就更有意思了。如果把一个子序列想象成一串数字项链,那么排列就是一串从 1 开始连续的数字项链,每个数字都恰好出现一次,而且这些数字是按升序排列的。这就好比你要从一堆数字卡片中挑选出一些卡片,这些卡片上的数字组合起来正好是从 1 开始连续的,不多不少,完美无缺。这就是小 R 梦寐以求的子序列排列啦。

测试样例像是小谜题:

  1. 样例1: - 输入:n=6n = 6a=[1,1,5,2,3,4]a = [1, 1, 5, 2, 3, 4] - 输出:1010 - 这就好比在一堆数字里找符合条件的组合,找到了10个。
  2. 样例2: - 输入:n=5n = 5a=[1,2,3,4,5]a = [1, 2, 3, 4, 5] - 输出:55 - 这里原数组本身就很整齐,符合条件的子序列有5个。
  3. 样例3: - 输入:n=7n = 7a=[1,3,5,2,2,4,6,7]a = [1, 3, 5, 2, 2, 4, 6, 7] - 输出:77 - 又是一堆数字,从中找到了7个符合要求的子序列。

解题思路像寻宝路线:

  1. 枚举子序列:这就像在一个大宝藏箱里,把所有可能的小宝藏(子序列)都翻出来看看。我们可以用位运算来巧妙地枚举所有子序列。
  2. 判断排列:对于每个翻出来的子序列,要检查它是不是排列。这就好比检查每个小宝藏是不是真金白银。我们可以用辅助数组记录已经出现过的数字,然后检查是否从1开始连续且不重复。 下面是一个简单的Python代码思路:
def solution(n: int, a: list) -> int: 
    count = 0 
    for i in range(1 << n): 
        subseq = [] 
        for j in range(n): 
            if (i & (1 << j)): 
                subseq.append(a[j]) 
        subseq.sort() 
        unique = [] 
        valid = True 
        for k in subseq: 
            if k not in unique: 
                unique.append(k) 
            else: 
                valid = False 
                break 
        if valid and len(unique) == len(subseq) and len(subseq) > 0 and min(subseq) == 1 and max(subseq) == len(subseq): 
            count += 1 
    return count

这个代码就像一把小铲子,帮我们把符合条件的子序列排列从数组这个大宝藏里挖出来啦!每个测试样例都是一个小关卡,用这个方法就能轻松闯关啦!