1 题目描述
学校在拍年度纪念照时,一般要求学生按照 非递减 的高度顺序排列。
请你返回至少有多少个学生没有站在正确位置数量。该人数指的是:能让所有学生以 非递减 高度排列的必要移动人数。
示例:
输入:[1,1,4,2,1,3]
输出:3
解释:
高度为 4、3 和最后一个 1 的学生,没有站在正确的位置。
提示:
1 <= heights.length <= 100
1 <= heights[i] <= 100
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/height-checker
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2 解题思路
这个题目的描述,是真的让人懵圈呢,非递减。。。
非递减的意思不就是递增吗老哥,升序排列,最直观的解决办法应该就是排序之后对比技术每个位置的不同数量。
这样子的话就涉及到比较排序,时间复杂度最低也有O(NlogN)。
但是实际上,好像并不需要排序,我们最终并不关心排序的结果,我们只需要知道在该位置上,与最小的值是否一致。
我们只需要进行计数,看某个数出现了多少次,前多少次应该出现,比较是否一致,不一致计数器就进行累加
恰巧,桶排序
满足这一点需求,就是把所有的相同的元素放进同一个桶里,统计其个数,然后将其按顺序取出来,这些元素就变成有序的了
我们这样子就比较简单的实现了排序和统计的工作
之前在学啊哈算法的时候,接触过桶排序,所以看起来并没有那么费劲
复杂度分析:
**时间复杂度:**O(n) ,计数过程为 O(n),比较过程外层循环次数固定为 100,里层循环一共也只会执行 n 次,O(100+n),也就是O(n)
**空间复杂度:**O(1) ,其中一个固定长度的计数数组与一个统计变量,与输入 N 的大小无关
作者:holy-sword
链接:https://leetcode-cn.com/problems/height-checker/solution/onjie-fa-yong-shi-yu-nei-cun-ji-bai-100-javayong-h/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
3 解决代码
class Solution {
public int heightChecker(int[] heights) {
//值的范围是有限定的,最多101
int[] arr= new int[101];
//遍历数组,只要在heights 里面,就要加一,这一步就是统计0,1,2等各个值有多少个
//桶排序的原理就是这样,先统计个数,然后再一个桶一个桶的取出来,这样元素就是有序的了
for(int height: heights){
arr[height]++;
}
//count是计数的,用来统计没有战对位置的元素
int count = 0;
//j是用来在heights中计数的, 取出来的那个元素是不是i相等的
int j = 0;
for(int i =1; i<arr.length;i++){
//arr[i],i是桶里面的元素,arr[i]是统计的i元素的个数
//arr[i]--, 表达的意思就是每次都取出来一个,一直取到没有元素成为桶
while(arr[i]-- >0){
//比较i和height中的元素,如果不同,计数器加一
if(heights[j++]!= i){
count++;
}
}
}
return count;
}
}