数组递增连续唯一整数组计数:现有Java代码缺陷求助
问题分析
给定整数数组,需统计满足以下条件的组的总数:组内整数数值唯一,且构成连续递增无缺失的序列(如(1,2,3)有效,(1,3,4)因缺失2无效)。现有思路在处理非首尾位置的重复元素时失效,例如测试用例[3,4,4,5,6]的正确结果应为16,但原有算法无法得出该值。
正确算法步骤
- 统计数值出现频率:遍历数组,用哈希表记录每个整数的出现次数,用于后续计算重复元素的可选组合数。
- 提取连续数值段:将哈希表中的唯一数值排序,分割为若干连续递增的数值段(段内每个数比前一个大1,段间存在数值间隔)。
- 计算单个连续段的贡献:
对于每个连续段(包含数值x₁, x₂, ..., xₙ,对应频率c₁, c₂, ..., cₙ):- 遍历所有可能的连续子序列起点
i; - 从起点
i开始,依次扩展到终点j,维护当前子序列的组合乘积(初始为1); - 每扩展一个数值,将乘积乘以该数值的频率,并把乘积加到总结果中。
- 遍历所有可能的连续子序列起点
- 累加所有段的贡献:将每个连续段的计算结果相加,得到最终的有效组总数。
Java实现代码
import java.util.*; public class ContinuousGroupCounter { public static int countValidGroups(int[] nums) { // 统计每个数字的出现次数 Map<Integer, Integer> freqMap = new HashMap<>(); for (int num : nums) { freqMap.put(num, freqMap.getOrDefault(num, 0) + 1); } // 提取排序后的唯一数值列表 List<Integer> uniqueNums = new ArrayList<>(freqMap.keySet()); Collections.sort(uniqueNums); int total = 0; int n = uniqueNums.size(); int i = 0; // 分割连续段并计算贡献 while (i < n) { int start = i; // 找到当前连续段的终点 while (i + 1 < n && uniqueNums.get(i + 1) == uniqueNums.get(i) + 1) { i++; } // 遍历当前段的所有连续子序列 for (int j = start; j <= i; j++) { long product = 1; for (int k = j; k <= i; k++) { product *= freqMap.get(uniqueNums.get(k)); total += product; } } i++; } return total; } public static void main(String[] args) { // 示例输入测试 int[] example1 = {13, 11, 4, 12, 5, 4}; System.out.println(countValidGroups(example1)); // 输出11 // 问题测试用例 int[] testCase = {3, 4, 4, 5, 6}; System.out.println(countValidGroups(testCase)); // 输出16 } }
算法说明
- 频率统计:重复元素的每个实例都算不同的选择,因此每个数值的出现次数直接决定了选该数值的方式数。
- 连续段分割:只有连续数值才能组成有效组,非连续数值的组合无法满足条件,因此需单独处理每个连续段。
- 子序列乘积计算:对于每个连续子序列,组的数量等于子序列中各数值出现次数的乘积(每个数值选一个实例,组合数相乘),累加所有子序列的乘积即可得到该段的有效组数量。
内容的提问来源于stack exchange,提问作者Learner
相关产品推荐
相关产品推荐

