刷题笔记(1)——桶排序

题目描述

学校在拍年度纪念照时,一般要求学生按照 非递减 的高度顺序排列。

请你返回能让所有学生以 非递减 高度排列的最小必要移动人数。

注意,当一组学生被选中时,他们之间可以以任何可能的方式重新排序,而未被选中的学生应该保持不动

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/height-checker
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

示例

示例1:
输入:heights = [1,1,4,2,1,3]
输出:3

示例 2:
输入:heights = [5,1,2,3,4]
输出:5

示例 3:
输入:heights = [1,2,3,4,5]
输出:0

提示:
1 <= heights.length <= 100
1 <= heights[i] <= 100

解题思路1

非递减排序也就是升序排序。以实例1为例子,输入[1,1,4,2,1,3],我们可以借助一个数组去完成题目要求,题目已经明确了输入值的范围为1 <= heights[i] <= 100。那么我们可以创建一个int arr[101]数组,初始化数组的值全为0。
arr[101] = {0,0,0,0,0,0,0,………………};
然后遍历输入的数组,第一个数是1,我们就在对应的arr[1],位置上增加1,即将 arr[1]的值从 0 改为 1,表示数字“1”出现过了一次。同理,当输入的数字等于4的时候,我们在arr[4]的位置上增加1。等等
在例子数组中总共有3个1,1个2,1个3,1个4。所以当遍历完输入数组后,数组arr就会变成
arr[101]={0,3,1,1,1,0,0,0…………………};
在升序排序之后,数字小的肯定会排在前面,比如3个1肯定是在前面的,并且前3个位置都是1。因此我们只需要判断在该位置上是否与对应的值一致。由于数据范围中没有0,所以arr[0]肯定为0。
第一步:我们从第1位开始判断,arr[1]=3,第一位数据是3,索引值为1,表明1有三个,按照升序排列的结果前3位都应该是1。
第二步:arr[2]=1,数值为2的有一个,按照升序排列的结果前4位都应该是2.(前面已经有三个1了)。
……以此类推
然后如果输入的数组(设为heights)中的数据没有出现在上述应该有的位置,就是需要进行移动调整的数据,遇到这种数据我们就进行一次统计累加最终遍历完这个数组就可以得到结果了。
这种排序方法也称为桶排序,桶排序是最简单最快捷的排序方法。具体的解释可以参考: 算法1:最快最简单的排序——桶排序.

class Solution {
public:
    int heightChecker(vector<int>& heights) {
        int count = 0;
        int arr[101]={0};
        int len_array = sizeof(heights)/sizeof(heights[0]);
        for(int i=0;i<heights.size();i++)
        {
            arr[heights[i]]++;
        }
        for(int i=1,j=0; i<101; i++)
        {
            while(arr[i]-- > 0){
              if(heights[j++]!=i){count++;}
            }
        }
        return count;
    }
};

解题思路2

第二种解题思路比较方便快捷,不用管使用何种方式进行排序,我们只需要知道升序排序之后数组的样子,然后对比原数组,位置上的数值不一样的,就是需要移动的,那有多少个不一样就需要移动多少次。例如:输入的数组 和 升序排序后的结果分别为:
:---------:[1,1,4,2,1,3]
:---------:[1,1,1,2,3,4]
我们可以发现两个数组在位置2,4,5(从0开始)的数值不相等,共3处地方,所以最少要移动3次。代码:

class Solution {
public:
    int heightChecker(vector<int>& heights) {
        vector<int> arr; 
        arr= heights;
        sort(arr.begin(), arr.end());
        int count = 0;
        for(int i = 0 ; i < arr.size(); i++){
            if(arr[i] != heights[i])count++;
        }return count;
    }
};

小结

思路1和思路2有相似的地方,其实这个题目表面上是“排序问题”,但实际解题的时候上并不需要知道排序的过程,就是不需要知道数组里的元素是如何比较且如何交换位置的。两种解题思路其实是判断这个元素是否出现在了它应该出现的位置,如果不是,则需要交换,至于跟谁交换,在本题中并不需要了解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值