合并区间问题
问题描述
为了提高文章质量,每一篇文章(假设全部都是英文)都会有m民编辑进行审核,每个编辑独立工作,会把觉得有问题的句子通过下表记录下来,比如[1,10],1表示病句的第一个字符,10表示病句的最后一个字符。也就是从1到10着10个字符组成的句子,是有问题的。
现在需要把多名编辑有问题的句子合并起来,送个总编辑进行最终的审核。比如编辑A指出的病句是[1,10],[32,45];编辑B指出的病句是[5,16],[78,94]那么[1,10]和[5,16]是有交叉的,可以合并成[1,16][32,45][78,94]
输入描述:
编辑数量m,之后每行是每个编辑的标记的下表组合,第一个和最后一个下标用英文逗号分隔,每组下标之间用分号分隔
输出描述:
合并后的下标集合,第一个和最后一个下标用英文逗号分隔,每组下标之间用分号分隔。返回结果是从小到大递增排列
例:输入
3
1,10;32,45
78,94;5,16
80,100;200,220;16,32
输出: 1,45;78,100;200,220
方式一:
暴力解法,用了三层嵌套的循环。
第一层循环三行数据,
第二层循环每行数据的每个begin和end;(前两步可以先把二维的数据改成一个list或者map,就可以减少一层循环),
第三层循环已经排好顺序的结果集。把每个新的begin和end与结果集对比,合并到合适的位置。
缺点:判断条件很多,很多边界可能会考虑不周全。
第71行的判断条件内,会把begin 大于 结果集当前遍历的begin 的新区间向前合并,然后放到下次循环继续判断是否会向后合并。然后下次循环向keys链表中插入数据时,需要判断key是否已经存在。
1 package test; 2 3 import java.util.HashMap; 4 import java.util.LinkedList; 5 import java.util.Map; 6 import java.util.Scanner; 7 8 public class TestFind { 9 public static void main(String[] args) { 10 Scanner sc = new Scanner(System.in); 11 int num = Integer.parseInt(sc.nextLine()); 12 System.out.println(num); 13 String[] lines = new String[num]; 14 for (int i = 0; i < num; i++) { 15 lines[i] = sc.nextLine(); 16 } 17 18 LinkedList<Integer> keys = new LinkedList<>(); 19 LinkedList<Integer> keys2 = new LinkedList<>(); 20 Map<Integer, Integer> m = new HashMap<>(); 21 //遍历人数 22 for (int i = 0; i < num; i++) { 23 //遍历每个人的数据 24 boolean isInsert = false; 25 for (String it : lines[i].split(";")) { 26 int begin = Integer.parseInt(it.split(",")[0]); 27 int end = Integer.parseInt(it.split(",")[1]); 28 //比较key值,然后确定value 29 for (int j = 0; j < keys.size(); j++) { 30 Integer key = keys.get(j); 31 Integer value = m.get(key); 32 if (begin < key) { 33 if (end < key) { 34 m.put(begin, end); 35 if (keys.contains(begin)){ 36 keys2.set(j-1,begin); 37 }else{ 38 keys2.add(j, begin); 39 } 40 isInsert = true; 41 } else if (end >= key && end <= value) { 42 m.remove(key); 43 m.put(begin, value); 44 keys2.remove(j); 45 //2 10 17 46 if (keys.contains(begin)){ 47 keys2.set(j-1,begin); 48 }else{ 49 keys2.add(j, begin); 50 } 51 isInsert = true; 52 } else { 53 m.remove(key); 54 m.put(begin, end); 55 keys2.remove(j); 56 if (keys.contains(begin)){ 57 keys2.set(j-1,begin); 58 }else{ 59 keys2.add(j, begin); 60 } 61 isInsert = true; 62 } 63 } else if (begin == key) { 64 int max = Math.max(end, value); 65 m.put(begin, max); 66 isInsert = true; 67 } else { 68 if (begin <= value+1) { 69 if (end <= value) { 70 continue; 71 } else if (end > value) { 72 //把key作为begin,查看下次循环是否被合并,若是最后一个,不影响 73 m.put(key, end); 74 begin = key; 75 continue; 76 } 77 } else { 78 continue; 79 } 80 } 81 break; 82 } 83 if (!isInsert) { 84 m.put(begin, end); 85 if (!keys.contains(begin)){ 86 keys2.add(begin); 87 } 88 } 89 isInsert =false; 90 keys = (LinkedList<Integer>) keys2.clone(); 91 System.out.println(keys); 92 } 93 } 94 StringBuilder sb = new StringBuilder(); 95 for (int i = 0; i < keys.size(); i++) { 96 int key = keys.get(i); 97 int value = m.get(key); 98 sb.append(key+","+value+";"); 99 } 100 sb.delete(sb.length()-1,sb.length()-1); 101 System.out.println(keys); 102 System.out.println(sb); 103 } 104 105 }
方式二
待补全