5.27.2022 Lintcode附加练习 1897 会议室3

描述

你有一个当前会议列表intervals,里面表明了每个会议的开始和结束时间,以及一些会议室rooms。现在有一系列会议ask需要加入,逐个判断他们能否被安排进当前的会议列表中而不产生冲突。一个会议室在同一时间只能进行一场会议。每个询问都相互独立。

被安排的会议可以拆分。如果需要安排一个[2, 4]的会议,你可以把它分成[2, 3][3, 4]两段来进行。

保证输入可以被安排在rooms个会议室之中
保证任意一个会议的起始时间取值范围是 [1, 50000]
|Intervals| <= 50000
|ask| <= 50000
1 <= rooms <= 20

样例

例 1:

 
输入:
Intervals:[[1,2],[4,5],[8,10]],rooms = 1,ask: [[2,3],[3,4]]
输出: 
[true,true]
解释:
对于[2,3]的询问,我们可以安排一个会议室room0。
以下是room0的会议列表:
[[1,2],[2,3],[4,5],[8,10]]
对于[3,4]的询问,我们可以安排一个会议室room0。
以下是room0的会议列表:
[[1,2],[3,4],[4,5],[8,10]]

例 2:

 
输入:
[[1,2],[4,5],[8,10]]
1
[[4,5],[5,6]]
输出:
[false,true]

我的第一版 是错的 我把rooms理解成 上面的时间段顺序是固定的 如果 当 后面的时间段的头部比前面的头尾部大的话就是另一个room,但事实上好像是 一个ask可以最多被分成这么多个room的意思

public class Solution {
    /**
     * @param intervals: the intervals
     * @param rooms: the sum of rooms
     * @param ask: the ask
     * @return: true or false of each meeting
     */
    public boolean[] meetingRoomIII(int[][] intervals, int rooms, int[][] ask) {
        // Write your code here.
        boolean[] MR = new boolean[ask.length];
        int MRcount=0;
        ArrayList<ArrayList<ArrayList<Integer>>> Sintervals= new ArrayList<ArrayList<ArrayList<Integer>>>(rooms);
        for(int i=0; i < rooms; i++) {
            Sintervals.add(new ArrayList<ArrayList<Integer>>());
        }
        int count=0;
        int mark=0;
        if (rooms==1){
            for(int i=0;i<intervals.length;i++){
                ArrayList<Integer> c = new ArrayList<Integer>();
                c.add(intervals[i][0]);
                c.add(intervals[i][1]);
                Sintervals.get(0).add(c);
            }
        }else{
            for(int i=1;i<intervals.length;i++){       
                if(intervals[i][0]<intervals[i-1][1]){          
                    for (int j=mark;j<i;j++){
                        ArrayList<Integer> c = new ArrayList<Integer>();
                        c.add(intervals[j][0]);
                        c.add(intervals[j][1]);  
                        System.out.println(count); 
                        Sintervals.get(count).add(c);                  
                    } 
                    count++;
                    
                    mark=i;
                }
            }
            for (int j=mark;j<intervals.length;j++){
                        ArrayList<Integer> c = new ArrayList<Integer>();
                        c.add(intervals[j][0]);
                        c.add(intervals[j][1]);
                        Sintervals.get(count).add(c);                  
                    } 
        }
        if(Sintervals.get(0).size()>4){
            System.out.println(Sintervals.get(3).size());
        }
        for(int i=0;i<ask.length;i++){
            int[][] ask1= new int[ask[i][1]-ask[i][0]][2];
            count=0;
            for(int p=ask[i][0];p<ask[i][1];p++){
                ask1[count][0]=p;
                ask1[count][1]=p+1;
                count++;
            }
            boolean[] MRtest= new boolean[ask1.length];
            ArrayList<ArrayList<ArrayList<Integer>>> SintervalsTmp= new ArrayList<>(rooms);
            for(int p=0;p<rooms;p++)
                SintervalsTmp.add(new ArrayList<ArrayList<Integer>>());
            for (int p=0;p<Sintervals.size();p++){
                for(int k=0;k<Sintervals.get(p).size();k++){ 
                    SintervalsTmp.get(p).add(Sintervals.get(p).get(k));
                    
                }
            }
            for(int p=0;p<ask1.length;p++){
                
                for(int k=0;k<rooms;k++){
                    if(ask1[p][1]<=SintervalsTmp.get(k).get(0).get(0)){
                        ArrayList<Integer> c = new ArrayList();
                        c.add(ask1[p][0]);
                        c.add(ask1[p][1]);
                        SintervalsTmp.get(k).add(0,c);
                        MRtest[p]=true;            
                    }
                    else if(ask1[p][0]>=SintervalsTmp.get(k).get(SintervalsTmp.get(k).size()-1).get(1)){
                        MRtest[p]=true;  
                    }else{
                        
                        for(int j=1;j<SintervalsTmp.get(k).size();j++){
                            
                            if(ask1[p][1]<=SintervalsTmp.get(k).get(j).get(0)&&ask1[p][0]>=SintervalsTmp.get(k).get(j-1).get(1)){
                                ArrayList<Integer> c = new ArrayList();
                                c.add(ask1[p][0]);
                                c.add(ask1[p][1]);
                                SintervalsTmp.get(k).add(j,c);
                                MRtest[p]=true;
                                break;
                            }
                        
                        }
                    }
                }   
            
                if(MRtest[p]==true){
                    continue;
                }
                else{
                    MRtest[p]=false;
                }
            }
            System.out.println(MRtest.length);
            for(int p=0;p<MRtest.length;p++){
                
                System.out.println(MRtest[p]);
                if(MRtest[p]==false){
                    MR[MRcount]=false;
                    MRcount++;
                    break;
                }
                else if(p==MRtest.length-1){
                    MR[MRcount]=true;
                    MRcount++;
                }
            }

        }
        return MR;
    }
}

这是我第二次想出来的:很显然lintcode没有让我过因为代码效率太低 TT

public class Solution {
    /**
     * @param intervals: the intervals
     * @param rooms: the sum of rooms
     * @param ask: the ask
     * @return: true or false of each meeting
     */
    public boolean[] meetingRoomIII(int[][] intervals, int rooms, int[][] ask) {
        // Write your code here.
        Map<String,Integer> a = new HashMap<String,Integer>();
        boolean[] b = new boolean[ask.length];
        for (int i=0;i<intervals.length;i++){
            for(int j=intervals[i][0];j<intervals[i][1];j++){
                String t = Integer.toString(j)+","+Integer.toString(j+1);
                if(a.get(t)!=null){
                    a.put(t,a.get(t)+1);
                }
                else{
                    a.put(t,1);
                }
            }
        }
        for(int i=0;i<ask.length;i++){
            Map<String, Integer> aC= new HashMap(a);
            int[][] ask1= new int[ask[i][1]-ask[i][0]][2];
            int count=0;
            for(int p=ask[i][0];p<ask[i][1];p++){
                ask1[count][0]=p;
                ask1[count][1]=p+1;
                count++;
            }
            
            for(int p =0;p<ask1.length;p++){
                String t=Integer.toString(ask1[p][0])+","+Integer.toString(ask1[p][1]);
                if(aC.get(t)!=null){
                    if(aC.get(t)+1>rooms){
                        b[i]=false;
                        break;
                    }
                    else{
                        aC.put(t,aC.get(t)+1);
                        
                    }
                }
                else{
                    aC.put(t,1);
                }
                if(p==ask1.length-1)
                    b[i]=true;
            }
            
        }
        
        return b;
    }
}

 这是第三次:优化不动了

public class Solution {
    public boolean[] meetingRoomIII(int[][] intervals, int rooms, int[][] ask) {
        // Write your code here.
        Map<Integer,Integer> a = new HashMap<Integer,Integer>();
        boolean[] b = new boolean[ask.length];
        Arrays.fill(b, Boolean.TRUE);
        for (int i=0;i<intervals.length;i++){
            for(int j=intervals[i][0];j<intervals[i][1];j++){
                if(a.get(j)!=null){
                    a.put(j,a.get(j)+1);
                }
                else{
                    a.put(j,1);
                }
            }
        }
        
        for(int i=0;i<ask.length;i++){
            
            if(a.get(ask[i][0])!=null&&ask[i][1]-ask[i][0]==1){
                if(a.get(ask[i][0])+1>rooms){
                        b[i]=false;
                        
                    }
            }else{
                for(int p =ask[i][0];p<ask[i][1];p++){
                    if(a.get(p)!=null){
                        if(a.get(p)+1>rooms){
                            b[i]=false;
                            break;
                        }
                    }

                }
            }            
        }
        return b;
    }
}

贴一个可读性强的完美答案供日后研究 :

public class Solution {
    /**
     * @param intervals: the intervals
     * @param rooms: the sum of rooms
     * @param ask: the ask
     * @return: true or false of each meeting
     */
    public boolean[] meetingRoomIII(int[][] intervals, int rooms, int[][] ask) {
        // Write your code here.
        // 另一种的扫描线Event表示法,只是没有另外写Event class
        int[] events = new int[50001]; // events[i]: + 1表示一个会议开始,- 1 表示一个会议结束
        int maxEndTime = 0;
        for (int[] interval: intervals) {
            events[interval[0]]++;
            events[interval[1]]--;
            maxEndTime = Math.max(maxEndTime, interval[1]);
        }

        for (int[] query: ask) {
            maxEndTime = Math.max(maxEndTime, query[1]);
        }

        // 前缀和不断维护当前同时存在的会议;起终点只是会议状态发生变化的时候
        int numOfMeetings = 0; 
        int[] sum = new int[50001]; // sum[i] = 0 -> empty; sum[i] = 1 -> not empty
        for (int i = 0; i <= maxEndTime; i++) {
            numOfMeetings += events[i];
            // 这个时间在进行的会议数量到不到rooms个,还有空的会议室
            if (numOfMeetings < rooms) { 
                sum[i] = 0;
            } else {
                sum[i] = 1;
            }
        }

        // [l,r]要求sum[l...r-1]全为0,sum[l...r-1] = 0
        // prefixSum[r - 1 + 1] - prefixSum[l] = 0 <=> prefixSum[r] = prefixSum[l]
        int[] prefixSum = new int[sum.length + 1];
        prefixSum[0] = 0;
        for (int i = 1; i < prefixSum.length; i++) {
            prefixSum[i] = prefixSum[i - 1] + sum[i - 1];
        }

        boolean[] result = new boolean[ask.length];
        for (int i = 0; i < ask.length; i++) {
            int[] query = ask[i];
            int start = query[0];
            int end = query[1];
            
            result[i] = prefixSum[end] == prefixSum[start];
        }

        return result;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值