LeetCode 406. Queue Reconstruction by Height

来源:互联网 发布:淘宝助理使用 编辑:程序博客网 时间:2024/06/06 00:51

406. Queue Reconstruction by Height

一、问题描述

Suppose you have a random list of people standing in a queue. Each person is described by a pair of integers (h, k), where h is the height of the person and k is the number of people in front of this person who have a height greater than or equal to h. Write an algorithm to reconstruct the queue.

Note:
The number of people is less than 1,100.

二、输入输出

Example

Input:[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]Output:[[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]

三、解题思路

贪心算法

  • 涉及到两个数或者区间的都先尝试对数组进行排序,我们先简单的按照h从大到小来进行排序
  • 之所以需要从大到小,是因为在遍历的时候,我么可以把当前元素随便的往前移动。他的前面都是比他大的,这样移动之后不会对前面的元素造成影响。
  • 很多初学者疑问为什么数组下标要从0开始那?原因就是这样下标表示的意义就是当前元素前面有多少个元素!Bingo我们正好利用这个性质,k表示的就是他前面有几个比他大的元素。现在他前面的全都是比他大的,那么k是不是就是该元素的下标那。表示他前面有k个比他大的元素。
  • 反应到代码上就是先把元素记录下来,并从原数组中删除,再把他插入到指定位置。
  • 这里有个小问题,就是对于h相同的元素。比如 (5,2) (5,3) 这一组,题目中认为相等的在掐面的比较大后面的比较小。那么应该先排列谁那?加入我们先排列(5,3)它会被放到下标为3的位置。然后我们排列(5,2)他被放到下标为2的位置。问题来了,当(5,3)前面出现了(5,2)的时候,k1=3 不在正确,因为当(5,2)出现在前面的时候他比后面出现的5要大。所以我们应该先排列k小的,它相对于较大的k在数组的前面,这样我们放置较大k后,不会对他造成影响。这就是为什么Bigger2排序函数中增加了对x.first == y.first的单独处理。
class Solution {public:    static bool Bigger2(const pair<int,int>& x, const pair<int,int>& y){        if(x.first == y.first){//非常重要,如果h相同,必须让k小的在前面,这样先排k小的,之后再排k大的会在k小的后面,就不会造成影响了            return x.second < y.second;        }        return (x.first > y.first);    }    vector<pair<int, int>> reconstructQueue(vector<pair<int, int>>& people) {        sort(people.begin(), people.end(), Bigger2);        int n = people.size();        for (int i = 0; i < n;i++) {            int expect = people[i].second;            if(expect == i)continue;            pair<int,int> save = people[i];            people.erase(people.begin() + i);//删除原来的元素            people.insert(people.begin()+expect, save);        }        return people;    }};