打点计数器的区间合并|豆包MarsCode AI刷题

61 阅读3分钟

打点计数器的区间合并 问题描述: 小明想发明一台打点计数器,这个计数器有这样的一个功能:

  • 它可以接收一个递增的数据范围(形如[3, 9]),其中第一个数字代表起始,第二个数字代表结束
  • 这个数据范围中包含几个数字,打点计数器就会打几个点
  • 在传入的多组数据范围中,如果出现了范围的重复,机器则不会重复打点

你可以帮助小明算一算,在不同的情况下,计数器会打出几个点么?

算法思路: 1.暴力法:我们可以用两层for循环来遍历我们的数组,同时我们可以定义一个set集合来保存我们遍历过的数字,外面那层循环用来遍历二维数组,取得里边的一维数组,里面的那一层从获取到的一维数组中取出start = inputArray[i][0] ,end = inputArray[i][1],然后循环遍历start到end的位置,如果set集合里面没有,那么我就添加,如果有,那么我就跳过,具体的代码示例如下:

import java.util.HashSet;
import java.util.Set;

public class tmep {
    public static int solution(int[][] inputArray) {
        int m = inputArray.length;
        int result = 0;
        Set<Integer> set = new HashSet<>();
        for (int i = 0; i < m; i++) {
            int start = inputArray[i][0];
            int end = inputArray[i][1];
            for (int j = start; j <= end; j++) {
                int num = j;
                if (!set.contains(num)) {
                    result++;
                    set.add(num);
                }
            }
        }
        System.out.println(result);

        return result;
    }


    public static void main(String[] args) {
        //  You can add more test cases here
        int[][] testArray1 = {{1, 4}, {7, 10}, {3, 5}};
        int[][] testArray2 = {{1, 2}, {6, 10}, {11, 15}};

        System.out.println(solution(testArray1) == 9);
        System.out.println(solution(testArray2) == 12);
    }
}

思路二:定义一个List<int[]>集合,使用合并区间的思想将所有可以合并的区间进行合并,将不能合并的区间添加到集合中去,最后遍历集合元素,就可以得到最终的结果,灵感来源于Leetcode里的56.合并区间题目 具体的代码展示如下:

import java.util.*;

public class Main {
    public static int solution(int[][] inputArray) {
        //1.对区间的首元素进行排序
        Arrays.sort(inputArray, (a, b) -> Integer.compare(a[0], b[0]));
        // 2. 合并重叠的区间
        List<int[]> list = new ArrayList<>();
        int[] current = inputArray[0];
        for (int i = 1; i < inputArray.length; i++) {
            //如果当前区间的右边元素大于等于遍历区间的左边元素,说明这两个区间是可以合并的
            if (current[1] >= inputArray[i][0]) {
                current[1] = Math.max(current[1], inputArray[i][1]);
            } else {
                //到这个分支,说明没有合并区间,则这两个区间独立,我们可以吧之前的current区间添加到list集合中去
                list.add(current);
                //新出现的独立区间成为新的current区间
                current = inputArray[i];
            } 
        }
        //因为到最后,current区间是没有添加到list集合中去的,所以我们有添加最后一个区间,
        list.add(current);
        //3.计算合并后区间的点数   list集合中区间存的是每个区间的开头与结尾
        int result = 0;
        for (int[] array : list) {
            result += array[1] - array[0] + 1;
        }
        return result;
    }

    public static void main(String[] args) {
        int[][] testArray1 = {{1, 4}, {7, 10}, {3, 5}};
        int[][] testArray2 = {{1, 2}, {6, 10}, {11, 15}};

        System.out.println(solution(testArray1) == 9); 
        System.out.println(solution(testArray2) == 12); 
    }
}

总的来说,多去了解不同的题型,多去做不同的题,对解决问题时,说不定会有不一样的想法。