zoukankan      html  css  js  c++  java
  • 406. Queue Reconstruction by Height

    最后更新

    二刷
    15-Jan-2016

    排座问题,记得以前是H难度的,现在改成M了。。

    总结一句话,先按身高排,高的在前面;身高一样的情况下,K小的在前面。

    BB半天说白了一句话,H大的在顶端,H一样的K小的在顶端。
    根据这句话设立PQ的判断规则就行了。。

    这样排的原因是因为出QUEUE的时候,后出的因为H小,不会影响前面的人。 而H一样的时候,虽然会影响前面同身高的,但是肯定K小的放前面,因为他能容忍比自己>=h的人更少。

    最后的问题就是返还是list of int[],所以得找个办法记录PERSON在原先队列的位置= =麻烦了不少。

    中间数组和LIST来回换很容易把自己弄晕= =||,有了这个做法也不想看别的做法了,拿到一个OFFER之后,我已经是一条咸鱼了。

    说好的拿到这个OFFER决不负自己呢?

    Time: O(NlogN)
    Space: O(N)

    public class Solution {
        public class Person {
            int height;
            int k;
            int index;
            public Person(int h, int k, int i) {
                this.height = h;
                this.k = k;
                this.index = i;
            }
        }
        
        public int[][] reconstructQueue(int[][] people) {
            
            PriorityQueue<Person> pq = new PriorityQueue<>(new Comparator<Person>() {
                public int compare(Person a, Person b) {
                    if (a.height != b.height) {
                        return Integer.compare(b.height, a.height);
                    } else {
                        return Integer.compare(a.k, b.k);
                    }
                }    
            });
            
            for (int i = 0; i < people.length; i++) {
                pq.offer(new Person(people[i][0], people[i][1], i));
            }
            
            // contain index of each person in the input array.
            List<Integer> refList = new ArrayList<>();
            
            while (!pq.isEmpty()) {
                Person tempPerson = pq.poll();
                refList.add(tempPerson.k, tempPerson.index);
            }
            
            int[][] res = new int[people.length][2];
            for (int i = 0; i < refList.size(); i++) {
                int pos = refList.get(i);
                res[i][0] = people[pos][0];
                res[i][1] = people[pos][1];
            }
            
            return res;
        }
    }
    

    一刷
    25-Sep-2016

    一开始backtrack,设计了很多剪枝情况,还是TLE了

    image

    。。后来用PQ做的。
    其实上面DFS做到一半的时候意识到应该用PQ做,但是不确定会不会TLE,就继续了,然后果然TLE了。。

    PQ的做法和剪枝的判断标准是一样的,只不过PQ不是遍历,比兼职纯遍历要快。

    想象一下排座位,h是身高,k是某个小朋友最多允许几个人挡住他(貌似不是很恰当)。

    对于单个小朋友来说,只有比他高才会挡住他,所以我们先按K的标准排最高的一批小朋友,这样一来后面批次的小朋友不会影响自己,因为永远不可能挡住自己。
    [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
    [7,0]和[7,1]先排好。
    同一批次里,K小的在前面,这个很好理解。。

    第二批小朋友是身高为6的,[6,1],他要保证只有1个人挡住他,他坐到刚才2个人之间就行了。
    [7,0] [6,1] [7,1]

    第三批是身高为5的,[5,0]和[5,2],[5,0]想近距离观察美女老师,而目前在坐的所有人都比他高,他就跑去第一排了。至于[5,2],性欲不那么旺盛,被2个人挡住也无所谓,于是坐到2个人后面。
    [5,0] [7,0] [6,1] [7,1]
    [5,0] [7,0] [5,2] [6,1] [7,1]
    然后是最后一个小朋友[4,4],他可能人比较耿直,正人君子,上课的时候心无旁骛,不需要看美女老师,所以前面4个人无所谓,他跑到4个人后面
    [5,0] [7,0] [5,2] [6,1] [4,4] [7,1]

    BB半天说白了一句话,H大的在顶端,H一样的K小的在顶端。
    根据这句话设立PQ的判断规则就行了。。

    这样排的原因是因为出QUEUE的时候,后出的因为H小,不会影响前面的人。 而H一样的时候,虽然会影响前面同身高的,但是肯定K小的放前面,因为他能容忍比自己>=h的人更少。

    public class Solution {
        
        public class People
        {
            public int h;
            public int k;
            public int i;   //index of this people in people[][]
            public People(int h, int k, int i)
            {
                this.h = h;
                this.k = k;
                this.i = i;
            }
        }
        public class compare implements Comparator<People>
    	{
    		public int compare(People p1, People p2)
    		{
    		    if(p1.h!=p2.h) return p2.h-p1.h;
    		    else return p1.k-p2.k;
    		}
    	}
    
        
        
        public int[][] reconstructQueue(int[][] people) 
        {
            if(people.length == 0) return new int[0][0];
    
            PriorityQueue<People> pq1 = new PriorityQueue(new compare());
            for(int i = 0; i < people.length;i++)
            {
                
                pq1.add(new People(people[i][0],people[i][1],i));
            }
            
            //index of people in people[][]
            List<Integer> l = new ArrayList<Integer>();
    
            while(!pq1.isEmpty())
            {
                People p = pq1.poll();
                l.add(p.k,p.i);
                
            }
            int[][] res = new int[people.length][2];
            for(int i = 0; i < l.size();i++)
            {
                res[i][0] = people[l.get(i)][0];
                res[i][1] = people[l.get(i)][1];
            }
            
            return res;
            
        }
    
    }
    
  • 相关阅读:
    491 · 回文数
    936 · 首字母大写
    1343 · 两字符串和
    1535 · 转换成小写字母
    13 · 字符串查找
    146 · 大小写转换 II
    241 · 转换字符串到整数(容易版)
    46 · 主元素
    kotlin协程——>通道
    kotlin协程——>异步流
  • 原文地址:https://www.cnblogs.com/reboot329/p/5908130.html
Copyright © 2011-2022 走看看