Java 中范围内双递增序列的计数

2024年9月10日 | 阅读 9 分钟

给出两个整数 P 和 Q。任务是找到一个系列的总计数,其中当前元素是系列中上一个元素的两倍或更多,并且该系列的任何元素都不能超过 P。它可以等于 P。

示例 1

输入

int P = 9, int Q = 3

输出 14

解释:共有 14 个大小为 3 的系列,当前元素是该系列上一个元素的两倍或更多,并且该系列的每个元素都小于或等于 9。所有这些系列是:{1, 2, 4}, {1, 2, 5}, {1, 2, 6}, {1, 2, 7}, {1, 2, 8}, {1, 2, 9}, {1, 3, 6}, {1, 3, 7}, {1, 3, 8}, {1, 3, 9}, {1, 4, 8}, {1, 4, 9}, {2, 4, 8}, {2, 4, 9}

示例 2

输入

int P = 12, int Q = 4

输出 10

解释:共有 10 个大小为 4 的系列,当前元素是该系列上一个元素的两倍或更多,并且该系列的每个元素都小于或等于 12。所有这些系列是:{1, 2, 4, 8}, {1, 2, 4, 9}, {1, 2, 4, 10}, {1, 2, 4, 11}, {1, 2, 4, 12}, {1, 2, 5, 10}, {1, 2, 5, 11}, {1, 2, 5, 12}, {1, 2, 6, 12}, {1, 3, 6, 12}

示例 3

输入

int P = 15, int Q = 7

输出 0

解释:不存在大小为 7 的系列,其中当前元素是前一个元素的两倍或更多,并且每个元素都小于或等于 15。因此,输出为 0。

朴素方法

在朴素方法中,我们将使用自顶向下的递归来找到解决方案。

文件名:DoubleIncSeq.java

输出

There are total 14 series whose elements are <= 9 and are of size: 3

There are total 10 series whose elements are <= 12 and are of size: 4

There is no series whose elements are <= 15 and is of size: 7

复杂度分析:一个递归调用会产生另外两个递归调用。因此,程序的 time complexity 是指数级的。

由于指数级的时间复杂度,上述程序不适用于较大的输入。因此,需要进行一些优化以降低时间复杂度。

方法:带记忆化的递归

在上述程序中有许多子问题被一遍又一遍地解决。因此,需要使用二维数组来存储已计算子问题的答案,以避免重复。下面的程序中说明了这一点。

文件名:DoubleIncSeq1.java

输出

There are total 14 series whose elements are <= 9 and are of size: 3

There are total 10 series whose elements are <= 12 and are of size: 4

There is no series whose elements are <= 15 and is of size: 7

复杂度分析:由于记忆化,程序的 time complexity 为 O(p x q)。此外,该程序使用辅助数组来存储子问题的答案,使得程序的 space complexity 为 O(p x q),其中 p 是所需系列中元素的最大可能值,q 是找到的系列总数。

众所周知,迭代方法总是优于递归方法,因此我们将尝试使用循环来编写上述程序。

文件名:DoubleIncSeq2.java

输出

There are total 14 series whose elements are <= 9 and are of size: 3

There are total 10 series whose elements are <= 12 and are of size: 4

There is no series whose elements are <= 15 and is of size: 7

复杂度分析:该程序的时间复杂度和空间复杂度与前一个程序相同。