1. Question
Suppose you have a random list of people standing in a queue. Each person is described by a pair of integers(h, k)
, whereh
is the height of the person andk
is the number of people in front of this person who have a height greater than or equal toh
. Write an algorithm to reconstruct the queue.
Note:
The number of people is less than 1,100.
Example
Copy 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]]
2. Implementation
(1) Sorting
思路:
(1) 根据题意,我们发现两点:1.最矮的人不会影响其他人的位置, 2. 在最矮的人群中,k的值最高的那个人不会影响其他人的位置。
(2) 基于这两点,我们可以将输入数组按照以下规则排序,先按高度从高到低排, 如果高度相同,则将index(第二个元素)的数从小到大排,排好序后,第二个元素则为该数组所处的位置
Copy class Solution {
public int [][] reconstructQueue ( int [][] people) {
Arrays . sort (people , new Comparator < int []>() {
@ Override
public int compare ( int [] a , int [] b) {
return a[ 0 ] == b[ 0 ] ? a[ 1 ] - b[ 1 ] : b[ 0 ] - a[ 0 ];
}
});
List < int []> list = new ArrayList <>();
for ( int [] info : people) {
list . add (info[ 1 ] , info);
}
int [][] res = new int [ people . length ][ 2 ];
for ( int i = 0 ; i < people . length ; i ++ ) {
res[i][ 0 ] = list . get (i)[ 0 ];
res[i][ 1 ] = list . get (i)[ 1 ];
}
return res;
}
}
(2) Binary Search Tree
1.第一步还是先对people数组排序,将高的排在前面,同样高度的话按照第二元素的值升序排。
2.第二步自定义Binary Search Tree, treeNode包含leftCount代表对当前node里的这个人有多少人是比他高。由于我们是按照高度从高到矮插入bst中,所以对于当前要插入的node(这个node代表的人的高度必然不比当前bst每个node个高度高),如果它的k值(每个数组第二个元素)比curNode的leftCount小,说明curNode代表的人的高度不会影响要插入node的位置,所以node要在curNode的左边,否则node要在curNode右边,注意在右边的话, k值要减去curNode.leftCount,因为在插入bst的过程中,我们已经知道有多少人比要插入node的人的高度高。
3.最后对bst做一个inorder traversal,得到最后结果
4.这种方法有机会将时间复杂度从O(n^2)降为O(nlogn),但由于树不能保证是balanced的,所以最坏情况还是O(n^2)
Copy class Solution {
class TreeNode {
int leftCount;
int [] people;
TreeNode left , right;
public TreeNode ( int [] people) {
this . people = people;
leftCount = 1 ;
this . left = null ;
this . right = null ;
}
}
public int [][] reconstructQueue ( int [][] people) {
int [][] res = new int [ people . length ][ 2 ];
if (people == null || people . length == 0 ) {
return res;
}
Arrays . sort (people , new Comparator < int []>(){
@ Override
public int compare ( int [] a , int [] b) {
return a[ 0 ] == b[ 0 ] ? a[ 1 ] - b[ 1 ] : b[ 0 ] - a[ 0 ];
}
});
TreeNode root = new TreeNode(people[ 0 ]) ;
for ( int i = 1 ; i < people . length ; i ++ ) {
insert(root , new TreeNode(people[i]) , people[i][ 1 ]) ;
}
inorderTraverse(root , res) ;
return res;
}
public void insert ( TreeNode root , TreeNode newNode , int k) {
TreeNode curNode = root;
while (curNode != null ) {
if (k < curNode . leftCount ) {
++ curNode . leftCount ;
if ( curNode . left == null ) {
curNode . left = newNode;
break ;
}
else {
curNode = curNode . left ;
}
}
else {
if ( curNode . right == null ) {
curNode . right = newNode;
break ;
}
else {
k -= curNode . leftCount ;
curNode = curNode . right ;
}
}
}
}
public void inorderTraverse ( TreeNode root , int [][] res) {
Stack < TreeNode > stack = new Stack() ;
TreeNode curNode = root;
int index = 0 ;
while (curNode != null || ! stack . isEmpty ()) {
if (curNode != null ) {
stack . push (curNode);
curNode = curNode . left ;
}
else {
curNode = stack . pop ();
res[index] = curNode . people ;
++ index;
curNode = curNode . right ;
}
}
}
}
3. Time & Space Complexity
Sorting: 时间复杂度O(nlogn + n^2) => O(n^2), 空间复杂度O(n), n为people数组的长度
Binary Tree: 时间复杂度:平均O(nlogn),最坏O(n^2), 空间复杂度O(n)