1. 程式人生 > >Expm 8_1 區間劃分問題

Expm 8_1 區間劃分問題

ack 大於等於 設計與實現 heap 時間排序 tel tro display ++

【問題描述】

給定一組報告,其中的每個報告設置了一個開始時間si和結束時間fi。設計與實現一個算法,對這組報告分配最少數量的教室,使得這些報告能無沖突的舉行。

技術分享圖片
 1 package org.xiu68.exp.exp8;
 2 
 3 import java.util.ArrayList;
 4 import java.util.Comparator;
 5 
 6 public class Exp8_1 {
 7 
 8     public static void main(String[] args) {
 9         // TODO Auto-generated method stub
10 ArrayList<Report> reports=new ArrayList<>(); 11 reports.add(new Report(7,10)); 12 reports.add(new Report(8,11)); 13 reports.add(new Report(9,13)); 14 reports.add(new Report(12,14)); 15 reports.add(new Report(13,15));
16 intervalPartition(reports); 17 } 18 19 public static void intervalPartition(ArrayList<Report> reports){ 20 reports.sort(new comp()); //按開始時間對報告進行排序 21 22 //不使用優先隊列 23 //ArrayList<Integer> classrooms=new ArrayList<>(); 24 //
classrooms.get(i)表示第i間教室的報告的結束時間 25 //classrooms.add(reports.get(0).endTime); 26 27 //使用優先隊列 28 PriorityQueue<ClassRoom> classrooms=new PriorityQueue<>(); 29 //首先為第1份報告分配教室 30 classrooms.add(new ClassRoom(reports.get(0).endTime)); 31 32 for(int i=1;i<reports.size();i++){ 33 //不使用優先隊列 34 /*boolean flag=false; //是否找到教室 35 for(int j=0;j<classrooms.size();j++){ 36 if(reports.get(i).startTime>=classrooms.get(j)){ //找到教室 37 classrooms.set(j, reports.get(i).endTime); 38 flag=true; 39 break; 40 } 41 } 42 if(flag==false){ //找不到教室,另分配一間教室 43 classrooms.add(reports.get(i).endTime); 44 }*/ 45 46 //使用優先隊列 47 if(reports.get(i).startTime>=classrooms.getMin().endTime){ //找到教室 48 //教室來了新報告後需要調整使用教室的結束時間 49 classrooms.setFirstElement(new ClassRoom(reports.get(i).endTime)); 50 }else{ 51 classrooms.add(new ClassRoom(reports.get(i).endTime)); //找不到教室,新開辟一間教室 52 } 53 54 } 55 System.out.println("最少需要 "+classrooms.size()+" 間教室"); 56 } 57 58 } 59 60 class Report{ 61 public int startTime; //開始時間 62 public int endTime; //結束時間 63 64 public Report(int startTime, int endTime) { 65 super(); 66 this.startTime = startTime; 67 this.endTime = endTime; 68 } 69 } 70 71 class ClassRoom implements Comparable<ClassRoom>{ 72 public int endTime; 73 public ClassRoom(int endTime){ 74 this.endTime=endTime; 75 } 76 @Override 77 public int compareTo(ClassRoom o) { 78 // TODO Auto-generated method stub 79 if(endTime>o.endTime) 80 return 1; 81 else 82 return -1; 83 } 84 } 85 class comp implements Comparator<Report>{ 86 @Override 87 //按開始時間排序報告的比較方法 88 public int compare(Report r1, Report r2) { 89 // TODO Auto-generated method stub 90 if(r1.startTime>r2.startTime) 91 return 1; 92 else 93 return -1; 94 } 95 }
View Code

技術分享圖片
  1 package org.xiu68.exp.exp8;
  2 
  3 import java.util.Comparator;
  4 import java.util.NoSuchElementException;
  5 
  6 
  7 public class PriorityQueue<E extends Comparable<E>> {
  8     private E[] heap;
  9     private int size;
 10     private Comparator<E> comp;
 11     
 12     @SuppressWarnings("unchecked")
 13     public PriorityQueue(){
 14         heap=(E[])new Comparable[5];
 15     }
 16     public PriorityQueue(Comparator<E> comp){
 17         this();
 18         this.comp=comp;
 19     }
 20     
 21     @SuppressWarnings("unused")
 22     private int compare(E e1,E e2){
 23         if(comp==null)
 24             return e1.compareTo(e2);
 25         else
 26             return comp.compare(e1, e2);
 27     }
 28     
 29     @SuppressWarnings("unchecked")
 30     public void add(E element){
 31         //如果添加元素後數組已滿,則先擴容再加入
 32         if(++size==heap.length){
 33             E[] e=(E[])new Comparable[heap.length*2];
 34             System.arraycopy(heap, 0, e, 0, size);
 35             heap=e;
 36         }
 37         heap[size-1]=element;
 38         adjust();
 39     }
 40     
 41     //設置堆頂元素,需要從堆頂開始調整堆
 42     public void setFirstElement(E element){
 43         if(size<=0){
 44             throw new NoSuchElementException();
 45         }
 46         heap[0]=element;
 47         adjustFromIndex(0);
 48     }
 49     public void adjustFromIndex(int i){
 50         //由於從序號為0開始存儲,需要加這段
 51         if(i==0 && size>1){
 52             int j;
 53             if(size>2){        //大於等於3個元素
 54                  j=(compare(heap[i+1],heap[i+2])>0?i+1:i+2);  //j為左右孩子的最小者的下標
 55             }else{          //只有兩個元素
 56                  j=i+1;
 57             }
 58             if(compare(heap[i],heap[j])>0){    //父結點大於子結點,交換值
 59                 E temp=heap[i];
 60                 heap[i]=heap[j];
 61                 heap[j]=temp;
 62             }
 63             adjustFromIndex(j);
 64         }
 65         
 66         int parent=i;
 67         int child=2*i;
 68         while(child<=size-1){
 69             //child<size-1表示parent左右孩子都存在
 70             //child存放左右孩子最大者數組下標
 71             if(child<size-1 && compare(heap[child],heap[child+1])>0){ 
 72                 child+=1;
 73             }
 74             if(compare(heap[parent],heap[child])<=0){  //父結點大於子結點,停止調整
 75                 break;
 76             }else{
 77                 E temp=heap[parent];
 78                 heap[parent]=heap[child];
 79                 heap[child]=temp;
 80                 parent=child;
 81                 child=2*parent;
 82             }
 83         }
 84     }
 85     //從新加入元素開始調整堆
 86     public void adjust(){
 87         int newElement=size-1;
 88         int parentElement;
 89         while(newElement>0){                //還沒有調整到根結點
 90             parentElement=newElement/2;        //根結點為newElement/2向下取整
 91             
 92             //如果父結點小於等於子結點則不需要調整
 93             if(compare(heap[parentElement],heap[newElement])<=0){
 94                 break;
 95             }
 96             //交換父結點與子結點的值
 97             E temp=heap[parentElement];
 98             heap[parentElement]=heap[newElement];
 99             heap[newElement]=temp;
100             newElement=parentElement;
101         }
102     }
103     //獲取最小元素
104     public E getMin(){
105         if(size==0){
106             throw new NoSuchElementException();
107         }
108         return heap[0];
109     }
110     //返回隊列大小
111     public int size(){
112         return size;
113     }
114 }
View Code

Expm 8_1 區間劃分問題