一、题目
1.题目描述
给你一个整数数组 nums ,请你将数组按照每个值的频率 升序 排序。如果有多个值的频率相同,请你按照数值本身将它们 降序 排序。
请你返回排序后的数组。
提升:
- 1 <= nums.length <= 100
- -100 <= nums[i] <= 100
2. 题目链接
二、解题报告
1.思路
- 统计每个数出现的频次计数,值的范围是-100~100
int[] cnt = new int[201];
for(int num: nums){
cnt[num + 100]++;
}
- 定义一个新数,使得新数能够经过排序后实现频率升序,按照数值降序的效果
- 满足频率升序,可以将频次数组乘以一个大于整数数组最大值的数,即
nums[i] = 201 * cnt[nums[i] + 100];
- 满足数值降序,则需要在频率相同时,数值大的变得更小,减去本身即可。本题考虑到统计频次时,对每个数都增加了100,即
nums[i] = 201 * cnt[nums[i] + 100] - nums[i] + 100;
- 对新数排序
- 将新数转换为原数
- 转换公式粗略表示为:
y = 201 ∗ k − x + 100 y = 201 * k - x+100 y=201∗k−x+100
y m o d ( 201 ) = − x + 100 y mod( 201) = -x + 100 ymod(201)=−x+100
2.代码实现
class Solution {
public int[] frequencySort(int[] nums) {
int[] cnt = new int[201];
for(int num: nums){
cnt[num + 100]++;
}
for(int i = 0; i < nums.length; i++){
//201 * cnt[] 满足按照频次排序
// - nums[] + 100 数值越大的,占比越小
nums[i] = 201 * cnt[nums[i] + 100] - nums[i] + 100;
}
Arrays.sort(nums);
//转换规则: x = 201 * k - y + 100
//x % 201 = -y + 100
for(int i = 0; i < nums.length; i++){
nums[i] = 100 - nums[i] % 201;
}
return nums;
}
}