You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中如何遍历多组重叠区间实现全范围值无重复无遗漏遍历

区间无重复遍历实现方案

核心规则说明

给定两个等长int数组start和end,start[i]、end[i]分别对应第i个闭区间的起点和终点,需要按数组索引从0到n-1的顺序遍历所有区间覆盖的整数,满足两个核心要求:

  • 所有区间覆盖的整数全部遍历到,无遗漏
  • 同一个整数不重复遍历,已经安排到后续区间遍历的数值,当前区间不重复处理

示例给定的输入如下:

int[] start = {1, 3, 4};
int[] end = {6, 10, 5};

最终覆盖的完整数值范围是1...10。

实现思路

核心逻辑非常直白:对于第i个区间里的任意整数,如果这个数会出现在i之后的任意一个区间里,就留给后续的区间去遍历,当前区间只处理那些后续不会再出现的数。
这个逻辑天然满足无重复、无遗漏的要求:每个整数一定会属于至少一个区间,我们只需要在包含它的索引最大的那个区间里遍历它即可,既不会提前在前面的区间重复处理,也不会因为所有区间都跳过而遗漏。
如果需要完全匹配示例里的端点归属(比如公共端点3归第0个区间遍历),只需要微调端点的判断条件即可,不影响核心逻辑。

代码实现

易懂版(适合小数据量场景)

逻辑直白不易错,不需要复杂预处理,直接按规则模拟即可:

public class IntervalTraversal {
    public static void main(String[] args) {
        int[] start = {1, 3, 4};
        int[] end = {6, 10, 5};
        int n = start.length;

        // 按索引顺序处理每个区间
        for (int i = 0; i < n; i++) {
            int curS = start[i];
            int curE = end[i];
            System.out.printf("区间%d[%d,%d] 遍历数值:", i, curS, curE);

            for (int num = curS; num <= curE; num++) {
                boolean hasInLater = false;
                // 检查当前数是否在后续任意区间中存在
                for (int j = i + 1; j < n; j++) {
                    if (num >= start[j] && num <= end[j]) {
                        hasInLater = true;
                        break;
                    }
                }
                // 后续不存在则当前遍历
                if (!hasInLater) {
                    System.out.print(num + " ");
                }
            }
            System.out.println();
        }
    }
}

运行输出:

区间0[1,6] 遍历数值:1 2 
区间1[3,10] 遍历数值:3 6 7 8 9 10 
区间2[4,5] 遍历数值:4 5 

可以看到所有1-10的数全部被遍历,无重复无遗漏。如果要完全匹配示例里把3归到第0个区间的效果,只需要把后续区间的判断条件从num >= start[j]改成num > start[j],再增加一个已遍历集合做去重即可,本质只是闭区间端点的归属规则差异。

优化版(适合大数据量场景)

如果区间范围很大(比如覆盖到百万级数值),上面的逐数判断效率较低,可以先从后往前预处理,维护后续区间的合并集合,把时间复杂度降到O(nlogn):

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class IntervalTraversalOpt {
    // 区间结构
    static class Range {
        int s;
        int e;
        public Range(int s, int e) {
            this.s = s;
            this.e = e;
        }
    }

    public static void main(String[] args) {
        int[] start = {1, 3, 4};
        int[] end = {6, 10, 5};
        int n = start.length;
        List<Range> laterRanges = new ArrayList<>();

        for (int i = n-1; i >=0 ; i--) {
            int curS = start[i];
            int curE = end[i];
            System.out.printf("区间%d[%d,%d] 遍历数值:", i, curS, curE);

            // 求当前区间和后续所有区间的差集,就是当前需要遍历的段
            List<Range> needTraverse = new ArrayList<>();
            needTraverse.add(new Range(curS, curE));
            for (Range r : laterRanges) {
                List<Range> temp = new ArrayList<>();
                for (Range cur : needTraverse) {
                    // 没有交集直接保留
                    if (cur.e < r.s || cur.s > r.e) {
                        temp.add(cur);
                        continue;
                    }
                    // 有交集,切掉重叠部分
                    if (cur.s < r.s) {
                        temp.add(new Range(cur.s, r.s -1));
                    }
                    if (cur.e > r.e) {
                        temp.add(new Range(r.e +1, cur.e));
                    }
                }
                needTraverse = temp;
            }

            // 输出当前需要遍历的段
            for (Range r : needTraverse) {
                for (int num = r.s; num <= r.e; num++) {
                    System.out.print(num + " ");
                }
            }
            System.out.println();

            // 把当前区间合并到后续区间集合中,供前一个i使用
            laterRanges.add(new Range(curS, curE));
            // 合并重叠区间,减少后续计算量
            laterRanges.sort(Comparator.comparingInt(a -> a.s));
            List<Range> merged = new ArrayList<>();
            for (Range r : laterRanges) {
                if (merged.isEmpty()) {
                    merged.add(r);
                    continue;
                }
                Range last = merged.get(merged.size()-1);
                if (r.s <= last.e +1) {
                    last.e = Math.max(last.e, r.e);
                } else {
                    merged.add(r);
                }
            }
            laterRanges = merged;
        }
    }
}

内容的提问来源于stack exchange,提问作者HARSH ASHRA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 23:03:24