區間合併(Java)
阿新 • • 發佈:2019-01-07
區間合併
題目描述:給出多組區間,求所有區間的交集
輸入描述:多個區間,單個區間用逗號隔開,區間之間用空格隔開,例如:2,6 3,8 6,9
輸出描述:將合併後的區間輸出,例如2,6 3,8 6,9合併後輸出2,9 1,3 2,6 8,10合併後輸出1,6 8,10
import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Scanner; /* class Interval { int start,end; public Interval(int start, int end) { this.start = start; this.end = end; } } */ public class Test2 { public static void main(String[] args) { Scanner sc=new Scanner(System.in); String str=sc.nextLine(); List<Interval> list=new ArrayList<>(); String[] s=str.split(" "); for (int i = 0; i < s.length; i++) { String[] s1=s[i].split(","); Interval interval=new Interval(Integer.valueOf(s1[0]),Integer.valueOf(s1[1])); list.add(interval); } List<Interval> list1=new ArrayList<>(); list1=merge(list); Iterator<Interval> it=list1.iterator(); while(it.hasNext()){ Interval inter=it.next(); if(it.hasNext()==false) System.out.println(inter.start+","+inter.end); else System.out.print(inter.start+","+inter.end+" "); } } public static List<Interval> merge(List<Interval> intervals) { List<Interval> intervals1 = new ArrayList<>(); if (intervals.size() == 0) { return intervals; } for (int i = 0; i < intervals.size(); i++) { for (int j = i+1; j < intervals.size(); j++) { if (intervals.get(i).start > intervals.get(j).start) { Interval tem = intervals.get(i); intervals.set(i,intervals.get(j)); intervals.set(j,tem); } } } int min = intervals.get(0).start; int max = intervals.get(0).end; for (int i = 1; i < intervals.size(); i++) { //重疊即合併區間 if (intervals.get(i).start <= max) { max = intervals.get(i).end > max ? intervals.get(i).end : max; } else { intervals1.add(new Interval(min,max)); min = intervals.get(i).start; max = intervals.get(i).end; } } intervals1.add(new Interval(min,max)); return intervals1; } }
連結串列解法
import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.LinkedList; import java.util.Scanner; class Interval { int start,end; public Interval(int start, int end) { this.start = start; this.end = end; } } public class Main { public static void main(String[] args) { Scanner sc=new Scanner(System.in); String str=sc.nextLine(); List<Interval> list=new LinkedList<>(); String[] s=str.split(" "); for (int i = 0; i < s.length; i++) { String[] s1=s[i].split(","); Interval interval=new Interval(Integer.valueOf(s1[0]),Integer.valueOf(s1[1])); list.add(interval); } list=merge(list); Iterator<Interval> it=list.iterator(); while(it.hasNext()){ Interval inter=it.next(); if(it.hasNext()==false) System.out.println(inter.start+","+inter.end); else System.out.print(inter.start+","+inter.end+" "); } } public static List<Interval> merge(List<Interval> intervals) { List<Interval> result = new LinkedList<>(); if (intervals == null || intervals.size() < 1) { return result; } // 先對區間進行排序,使用一個匿名內部類 Collections.sort(intervals, new Comparator<Interval>() { @Override public int compare(Interval o1, Interval o2) { return o1.start - o2.start; } }); // 排序後,後一個元素(記為next)的start一定是不小於前一個(記為prev)start的, // 對於新加入的區間,假設next.start大於prev.end就說明這兩個區間是分開的,要添 // 加一個新的區間。否則說明next.start在[prev.start, prev.end]內。則僅僅要看 // next.end是否是大於prev.end,假設大於就要合併區間(擴大) Interval prev = null; for (Interval item : intervals) { if (prev == null || prev.end < item.start) { result.add(item); prev = item; } else if (prev.end < item.end) { prev.end = item.end; } } return result; } }