求修正:统计升序列表中5个连续递增数字序列数量的代码问题
问题分析
原代码的逻辑完全偏离了需求——它在统计相同元素连续出现5次的次数,但我们需要的是统计由5个连续递增数字(如1,2,3,4,5)组成的序列的数量,而且每个元素只能被使用一次(用完就从可用池中移除)。
比如给定列表[1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5],每个数字的可用次数是:1→3,2→2,3→3,4→3,5→2。每次凑一组1,2,3,4,5就消耗每个数字各1次,最多能凑2组(因为2和5只有2次可用),所以返回2。
解决方案
我们可以先用一个频率表统计每个数字的出现次数,然后从最小的数字开始,依次检查连续的5个数字是否都有剩余可用次数,每凑成一组就减少对应数字的计数,并增加统计结果。循环这个过程直到无法凑出完整的连续序列为止。
修正后的代码
import java.util.List; import java.util.Map; import java.util.TreeMap; public static int countConsecutiveGroups(List<Integer> list) { // 用TreeMap保证数字按升序排列 Map<Integer, Integer> freqMap = new TreeMap<>(); for (int num : list) { freqMap.put(num, freqMap.getOrDefault(num, 0) + 1); } int count = 0; // 循环检查是否还能凑出连续5个递增数字的序列 while (true) { Integer currentNum = null; int sequenceLength = 0; // 遍历排序后的数字,尝试构建连续序列 for (Map.Entry<Integer, Integer> entry : freqMap.entrySet()) { int num = entry.getKey(); if (entry.getValue() == 0) { continue; } if (currentNum == null) { currentNum = num; sequenceLength = 1; } else if (num == currentNum + 1) { currentNum = num; sequenceLength++; // 凑够5个连续数字,统计一次并更新频率 if (sequenceLength == 5) { count++; // 减少这5个数字的可用次数 for (int i = currentNum - 4; i <= currentNum; i++) { freqMap.put(i, freqMap.get(i) - 1); } // 找到一组后跳出循环,重新开始检查 break; } } else { // 数字不连续,重置当前序列 currentNum = num; sequenceLength = 1; } } // 如果遍历完都没凑够5个连续数字,退出循环 if (sequenceLength < 5) { break; } } return count; }
代码解释
- 频率统计:用
TreeMap统计每个数字的出现次数,同时保证数字按升序排列,方便我们按顺序找连续递增的序列。 - 循环凑序列:每次遍历排序后的数字,尝试构建长度为5的连续递增序列。一旦凑够,就减少这5个数字的可用次数,统计数加1,然后重新开始检查(因为减少次数后可能又能凑出新的序列)。
- 终止条件:当遍历完所有数字都无法凑出长度为5的连续序列时,停止循环并返回统计结果。
测试给定例子的流程:
- 初始频率:1→3,2→2,3→3,4→3,5→2
- 第一次凑出序列后,频率变为1→2,2→1,3→2,4→2,5→1,count=1
- 第二次凑出序列后,频率变为1→1,2→0,3→1,4→1,5→0,count=2
- 第三次遍历的时候,到2时可用次数为0,无法凑够5个连续数字,循环终止,返回2,符合预期。
内容的提问来源于stack exchange,提问作者kekwsmurf
相关产品推荐
相关产品推荐

