持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情
1、前言
每天一个算法小练习,本篇使用Java实现。
2、题目描述
用x,y表示一个整数范围区间,现在输入一组这样的范围区间(用空格隔开),请输出这些区间的合并。
2.1、输入描述
一行整数,多个区间用空格隔开。区间的逗号是英文字符。
2.2、输出描述
合并后的区间,用过空格隔开,行末无空格。
2.3、示例1
输入:
1,3 2,5
输出:
1,5
2.4、示例2
输入:
1,3 2,5 8,10 11,15
输出:
1,5 8,10 11,15
3、解题思路
先把区间按区间的左端点从小到大排序,放入数组内,然后再把排序后的数组遍历一遍,如果下一个区间的开始比前一个区间的末尾要小,则表示这两个区间是重合的,就可以合并(用当下一个区间的右端点更新前一个区间的右端点,将其置为二者的较大值)。否则它们就不会重合,可以直接将这个区间加入数组的末尾;
4、实现代码
public class Merge {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String inputStr = sc.nextLine();
//将输入的字符串拆分
String[] strArr = inputStr.split(" ");
int[][] inputArr = new int[strArr.length][2];
for (int i = 0; i < strArr.length; i++) {
String strInt = strArr[i];
String[] splitStr = strInt.split(",");
int[] intervals = new int[]{Integer.parseInt(splitStr[0]), Integer.parseInt(splitStr[1])};
inputArr[i] = intervals;
}
int[][] merge = merge(inputArr);
for (int i = 0; i < merge.length; i++) {
int[] ints = merge[i];
for (int j = 0; j < ints.length; j++) {
System.out.print(ints[j]);
System.out.print(",");
}
System.out.print(" ");
}
}
public static int[][] merge(int[][] inputArr) {
if(inputArr.length<=0) {
return new int[0][0];
}
List<int[]> result=new ArrayList<>();
//对区间进行排序
Arrays.sort(inputArr, new Comparator<int[]>() {
@Override
public int compare(int[] a, int[] b) {
return a[0]-b[0];
}
});
result.add(inputArr[0]);
for(int i = 1; i < inputArr.length; i++) {
int right = result.get(result.size()-1)[1];
if(inputArr[i][0] <= right) {
//当前区间起始位置小于result最后一个元素的结束位置,这时就要进行合并
//合并区间。区间的结束位置 = max(当前遍历区间的结束位置,result最后一个区间的结束位置)
result.get(result.size()-1)[1] = Math.max(inputArr[i][1],right);
}else {
//不需要合并时的处理
result.add(inputArr[i]);
}
}
return result.toArray(new int[result.size()][2]);
}
}
5、执行结果
6、复杂度分析
- 时间复杂度:
n是区间的数量,因为刚开始要对所有区间进行排序,排序完成后,只需要遍历一次排好序的数组。
- 空间复杂度:
因为对所有区间进行排序时要用到额外空间,这里就是排序所需要的。
好了、本期就先介绍到这里,有什么需要交流的,大家可以随时私信我。😊