排序现象随处可见,考试名次、身高排序、年龄排序、网上购物价格排序、用户访问时间排序等等。
自己在刷leetcode数组简单算法题中遇到题目如下:
此题可以有多种解法,但其中的桶排序是最快最简单有效的
- 解法一:桶排序法
public int heightChecker(int[] heights) {
// 值的范围是1 <= heights[i] <= 100,因此需要1,2,3,...,99,100,共101个桶
int[] arr = new int[101];
// 遍历数组heights,计算每个桶中有多少个元素,也就是数组heights中有多少个1,多少个2,。。。,多少个100
// 将这101个桶中的元素,一个一个桶地取出来,元素就是有序的
for (int height : heights) {
arr[height]++;
}
int count = 0;
for (int i = 1, j = 0; i < arr.length; i++) {
// arr[i],i就是桶中存放的元素的值,arr[i]是元素的个数
// arr[i]-- 就是每次取出一个,一直取到没有元素,成为空桶
while (arr[i]-- > 0) {
// 从桶中取出元素时,元素的排列顺序就是非递减的,然后与heights中的元素比较,如果不同,计算器就加1
if (heights[j++] != i) count++;
}
}
return count;
}
在桶排序中,
首先我们其实并不关心排序后得到的结果,我们想知道的只是在该位置上,与最小的值是否一致
题目中已经明确了值的范围 1 <= heights[i] <= 100
这是一个在固定范围内的输入,比如输入: [1,1,4,2,1,3]
输入中有 3 个 1,1 个 2,1 个 3 和 1 个 4,3 个 1 肯定会在前面,依次类推
所以,我们需要的仅仅只是计数而已
- 解法二:
class Solution {
public int heightChecker(int[] heights) {
int[] nums = heights.clone();
Arrays.sort(nums);
int count = 0;
for(int i = 0 ; i < heights.length ; i ++){
if(nums[i] != heights[i]){
count++;
}
}return count;
}
}
只需比较排序后的数组与原来数组有几个不同,即为要调整的人数。