如何不修改输入消除子序列校验场景下循环后的重复条件代码
消除重复判断的实现方案
不需要修改输入参数,也无需封装重复调用的函数,以下两种方案均可直接实现无重复代码的逻辑:
方案1:扩展循环边界模拟终止中断
核心思路是让循环多执行一次,当遍历到数组长度位置(超出数组下标范围)时,直接触发子序列中断的逻辑,自动处理末尾的子序列统计,完全复用原有循环内的判断代码。
public static List<Integer> maxSubsequence(List<Integer> array) { int ind = 0; int bestInd = 0; int cnt = 1; int maxCnt = 0; // 循环终止条件从 < 改成 <=,多执行一次模拟末尾子序列中断 for(int i = 1; i <= array.size(); i++) { // 仅当i未超出数组范围时才做差值判断,否则直接判定为中断 if(i < array.size() && Math.abs(array.get(ind) - array.get(i)) <= 1) { cnt++; continue; } // 复用原有的最优子序列更新逻辑 if(cnt > maxCnt) { bestInd = ind; maxCnt = cnt; } // 仅当i未超出数组范围时才调整滑动窗口参数 if(i < array.size()) { if(Math.abs(array.get(ind) - array.get(i)) == 2) { cnt--; ind++; i--; } else { cnt = 1; ind = i; } } } return array.subList(bestInd, bestInd + maxCnt); }
该方案原有业务逻辑几乎不需要改动,仅新增了边界判断,测试序列5, 1, 2, 3, 3, 3的运行结果和原代码完全一致,输出为2, 3, 3, 3。
方案2:调整最优值更新时机
核心思路是把最优值更新的逻辑从「子序列中断时才触发」改成「每次计数更新后都触发」,不管子序列有没有中断,只要当前子序列长度变化就检查是否是最优值,这样末尾的子序列在计数完成后已经完成了最优值更新,不需要循环结束后额外判断。
public static List<Integer> maxSubsequence(List<Integer> array) { int ind = 0; int bestInd = 0; int cnt = 1; int maxCnt = 1; // 初始值改为1,因为子序列最小长度为1 bestInd = 0; // 初始最优位置从0开始 for(int i = 1; i < array.size(); i++) { if(Math.abs(array.get(ind) - array.get(i)) <= 1) { cnt++; // 每次计数更新后直接更新最优值 if(cnt > maxCnt) { bestInd = ind; maxCnt = cnt; } continue; } if(Math.abs(array.get(ind) - array.get(i)) == 2) { cnt--; ind++; i--; } else { cnt = 1; ind = i; } } return array.subList(bestInd, bestInd + maxCnt); }
内容的提问来源于stack exchange,提问作者vszholobov
相关产品推荐
相关产品推荐

