[Leetcode 1051] Height Checker

原题说明

Students are asked to stand in non-decreasing order of heights for an annual photo.

Return the minimum number of students that must move in order for all students to be standing in non-decreasing order of height.

Notice that when a group of students is selected they can reorder in any possible way between themselves and the non selected students remain on their seats.

 Example 1:

Input: heights = [1,1,4,2,1,3]
Output: 3
Explanation:
Current array : [1,1,4,2,1,3]
Target array : [1,1,1,2,3,4]
On index 2 (0-based) we have 4 vs 1 so we have to move this student.
On index 4 (0-based) we have 1 vs 3 so we have to move this student.
On index 5 (0-based) we have 3 vs 4 so we have to move this student.

Example 2:

Input: heights = [5,1,2,3,4]
Output: 5

Example 3:

Input: heights = [1,2,3,4,5]
Output: 0

Constraints:

  • 1 <= heights.length <= 100
  • 1 <= heights[i] <= 100

解题思路

这道题可以有很多做法。最高效的方法是:
建立一个数组height_to_num, 其indexheight,对应的值为height出现的次数,该数组可替代排序
遍历一遍heights数组来更新height_to_num
然后再遍历一遍heights数组,同时从height_to_num中找到排序后的高度sort_height,
比较heightsort_height, 如果不同则返回结果+1

示例代码 (cpp)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class Solution {
public:
// Use height as vector index to aovid sorting
int heightChecker(vector<int>& heights) {
vector<int> height_to_num = vector<int>(101, 0);
for (const auto height : heights) {
height_to_num[height]++;
}
int switch_count = 0;
int sort_height = 0;
for (const auto height : heights) {
while (height_to_num[sort_height] == 0) {
++sort_height;
}
if (sort_height != height) {
++switch_count;
}
height_to_num[sort_height]--;
}
return switch_count;
}
// use sort
// O(nlogn)
int heightChecker(vector<int>& heights) {
const auto original_heights = heights;
sort(heights.begin(), heights.end());
int switch_count = 0;
for (int i = 0; i < heights.size(); ++i) {
if (heights[i] != original_heights[i]) {
++switch_count;
}
}
return switch_count;
}
// use priority queue
// O(nlogn)
int heightChecker(vector<int>& heights) {
priority_queue<int, vector<int>, greater<int>> pq(heights.begin(), heights.end());
int switch_count = 0;
for (const auto height : heights) {
int sort_height = pq.top();
pq.pop();
if (sort_height != height) {
++switch_count;
}
}
return switch_count;
}
};

示例代码 (java)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution {
public int heightChecker(int[] heights) {
int[] heightToFreq = new int[101];

for (int height : heights) {
heightToFreq[height]++;
}

int result = 0;
int curHeight = 0;

for (int i = 0; i < heights.length; i++) {
while (heightToFreq[curHeight] == 0) {
curHeight++;
}

if (curHeight != heights[i]) {
result++;
}
heightToFreq[curHeight]--;
}

return result;
}
}

示例代码 (python)

1
2
3
class Solution:
def heightChecker(self, heights: List[int]) -> int:
return sum(h1 != h2 for h1, h2 in zip(heights, sorted(heights)))

复杂度分析

时间复杂度: O(N)
空间复杂度: O(height)

归纳总结

我们在Youtube上更新了视频讲解,欢迎关注!

------ 关注公众号:猩猩的乐园 ------