AI 刷题解析 134.区间内排列的数量 | 豆包MarsCode AI刷题

84 阅读4分钟

豆包MarsCode AI刷题记录——学习方法与心得

问题描述

小U拿到了一组排列,她想知道有多少个子区间满足区间内部的数构成一个排列。一个区间的排列是指:该区间的数包含从 11 到 kk 的每个数,并且每个数恰好出现一次,这个区间的长度为 kk。

例如,对于数组 [2, 1, 5, 3, 4],其中区间 [2, 2][1,2] 和 [1, 5] 都是排列。

题目解析

这个问题要求我们找到数组中所有长度为 k 的子区间,这些子区间内的元素构成从 1 到 k 的一个排列。排列是指每个数字恰好出现一次。

理解排列:一个长度为 k 的子数组是排列,当且仅当它包含从 1 到 k 的所有整数,每个整数恰好出现一次。

遍历所有子区间:为了找到所有满足条件的子区间,我们需要遍历数组中所有可能的子区间。这可以通过两个嵌套的循环实现,外层循环固定子区间的起始位置,内层循环固定子区间的结束位置。

检查子区间是否为排列:对于每个子区间,我们需要检查它是否是排列。检查的方法是看子区间内的元素集合是否等于从 1 到 k 的整数集合。我们可以通过将子区间的元素转换成集合,然后与包含 1 到 k 的整数集合进行比较来实现。

计数:每当找到一个符合条件的子区间,我们就增加计数器的值。

具体步骤如下:

  • 初始化一个计数器 count 为 0。
  • 使用两个嵌套循环,外层循环变量 i 表示子区间的起始位置,内层循环变量 j 表示子区间的结束位置。
  • 在内层循环中,检查子区间 a[i:j+1] 是否是排列。如果是,则将 count 加 1。
  • 最后返回 count 的值。

代码中,is_permutation 函数负责检查一个子区间是否是排列。它首先获取子区间的长度 k,然后比较子区间的元素集合与从 1 到 k 的整数集合是否相等。

在主函数 solution 中,我们遍历所有可能的子区间,并使用 is_permutation 函数检查每个子区间。如果子区间是排列,我们就增加计数器的值。

代码详解

def solution(n: int, a: list) -> int:
    def is_permutation(subarray):
        k = len(subarray)
        if k == 0:
            return False
        num_set = set(subarray)
        return num_set == set(range(1, k + 1))

    count = 0
    for i in range(n):
        for j in range(i, n):
            if is_permutation(a[i:j+1]):
                count += 1
    return count

if __name__ == '__main__':
    print(solution(5, [2, 1, 5, 3, 4]) == 3)
    print(solution(5, [1, 2, 3, 4, 5]) == 5)
    print(solution(4, [4, 3, 2, 1]) == 4)

知识点总结

  1. 数组与子数组

    • 数组是数据的集合,可以通过索引来访问。
    • 子数组是原数组中连续的一部分。
  2. 排列

    • 排列是指一个序列,其中每个元素恰好出现一次,并且包含了从 1 到某个数 k 的所有整数。
  3. 哈希表(字典)

    • 哈希表是一种数据结构,可以存储键值对,并且提供快速的查找、插入和删除操作。
    • 在这个问题中,我们使用哈希表来记录窗口内每个元素的出现次数。
  4. 滑动窗口

    • 滑动窗口是一种常用的算法技巧,用于处理数组或字符串中的连续子结构问题。
    • 通过两个指针(通常称为左右指针)来表示窗口的边界,并随着指针的移动来动态调整窗口的大小。
  5. 双指针技术

    • 双指针技术是指使用两个指针在数组或字符串中移动,以解决问题的一种方法。
    • 在滑动窗口中,一个指针用于扩展窗口,另一个指针用于收缩窗口。
  6. 集合操作

    • 集合操作包括并集、交集、差集等,可以用来快速判断两个集合是否相等。
  7. 算法优化

    • 在解决算法问题时,寻找更高效的解决方案是关键。
    • 从暴力解法到滑动窗口的优化,可以显著提高算法的效率。
  8. 边界条件处理

    • 在编写算法时,需要特别注意边界条件,如数组的起始和结束位置,以及窗口大小的调整。

复杂度分析

上面给出的方法的时间复杂度是 O(n^2),因为对于每个可能的 k 值,我们使用滑动窗口遍历整个数组一次。对于大多数情况,这个方法比暴力解法更高效。

AI刷题与python学习经验

分享一个补充基础语法的python学习网站,结合着豆包MarsCode AI刷题用很有效,感觉比啃书效率高一些。用AI刷题的话方便之处就是还能帮忙检查错误,其实一些可以避免的错误或者是机械性地工作交给AI去做挺好的,解放大脑去做更多创造性的工作。但是AI始终是工具,我们自己还是要学习,以便保持清醒的判断力。 image.png