Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LeetCode] 406. Queue Reconstruction by Height #406

Open
grandyang opened this issue May 30, 2019 · 2 comments
Open

[LeetCode] 406. Queue Reconstruction by Height #406

grandyang opened this issue May 30, 2019 · 2 comments

Comments

@grandyang
Copy link
Owner

grandyang commented May 30, 2019

 

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]]

 

这道题给了我们一个队列,队列中的每个元素是一个 pair,分别为身高和前面身高不低于当前身高的人的个数,让我们重新排列队列,使得每个 pair 的第二个参数都满足题意。首先来看一种超级简洁的方法,给队列先排个序,按照身高高的排前面,如果身高相同,则第二个数小的排前面。然后新建一个空的数组,遍历之前排好序的数组,然后根据每个元素的第二个数字,将其插入到 res 数组中对应的位置,参见代码如下:

 

解法一:

class Solution {
public:
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        sort(people.begin(), people.end(), [](vector<int>& a, vector<int>& b) {
            return a[0] > b[0] || (a[0] == b[0] && a[1] < b[1]);
        });
        vector<vector<int>> res;
        for (auto a : people) {
            res.insert(res.begin() + a[1], a);
        }
        return res;
    }
};

 

上面那种方法是简洁,但是用到了额外空间,我们来看一种不使用额外空间的解法,这种方法没有使用 vector 自带的 insert 或者 erase 函数,而是通过一个变量 cnt 和k的关系来将元素向前移动到正确位置,移动到方法是通过每次跟前面的元素交换位置,使用题目中给的例子来演示过程:

[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]

排序后:

[[7,0], [7,1], [6,1], [5,0], [5,2], [4,4]]

交换顺序:

[[7,0], [6,1], [7,1], [5,0], [5,2], [4,4]]

[[5,0], [7,0], [6,1], [7,1], [5,2], [4,4]]

[[5,0], [7,0], [5,2], [6,1], [7,1], [4,4]]

[[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]

 

解法二:

class Solution {
public:
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        sort(people.begin(), people.end(), [](vector<int>& a, vector<int>& b) {
            return a[0] > b[0] || (a[0] == b[0] && a[1] < b[1]);
        });
        for (int i = 1; i < people.size(); ++i) {
            int cnt = 0;
            for (int j = 0; j < i; ++j) {
                if (cnt == people[i][1]) {
                    auto t = people[i];
                    for (int k = i - 1; k >= j; --k) {
                        people[k + 1] = people[k];
                    }
                    people[j] = t;
                    break;
                }
                ++cnt;
            }
        }
        return people;
    }
};

 

下面这种解法跟解法一很相似,只不过没有使用额外空间,而是直接把位置不对的元素从原数组中删除,直接加入到正确的位置上,参见代码如下:

 

解法三:

class Solution {
public:
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        sort(people.begin(), people.end(), [](vector<int>& a, vector<int>& b) {
            return a[0] > b[0] || (a[0] == b[0] && a[1] < b[1]);
        });
        for (int i = 0; i < people.size(); i++) {
            auto p = people[i];
            if (p[1] != i) {
                people.erase(people.begin() + i);
                people.insert(people.begin() + p[1], p);
            }
        }
        return people;
    }
};

 

Github 同步地址:

#406

 

类似题目:

Count of Smaller Numbers After Self

 

参考资料:

https://leetcode.com/problems/queue-reconstruction-by-height/

https://leetcode.com/problems/queue-reconstruction-by-height/discuss/89348/6-lines-Concise-C%2B%2B

https://leetcode.com/problems/queue-reconstruction-by-height/discuss/89456/short-java-solution-without-using-extra-space

https://leetcode.com/problems/queue-reconstruction-by-height/discuss/89345/Easy-concept-with-PythonC%2B%2BJava-Solution

 

LeetCode All in One 题目讲解汇总(持续更新中...)

@skybluewing
Copy link

感谢分享不需要额外数组的方法,写的太好啦。一个小小的建议,第二种方法排序以后people[j].first >= people[i].first一定成立,所以感觉++cnt就可以了哈。另外,想请问一下,自带的sort应该用的是quick sort, 那面试的时候空间复杂度说多少好呢?

@grandyang
Copy link
Owner Author

感谢分享不需要额外数组的方法,写的太好啦。一个小小的建议,第二种方法排序以后people[j].first >= people[i].first一定成立,所以感觉++cnt就可以了哈。另外,想请问一下,自带的sort应该用的是quick sort, 那面试的时候空间复杂度说多少好呢?

嗯嗯,已改正,多谢指出~
快排的空间复杂度也是 O(nlgn),再加上其他的就好了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants