leetcode算法刷题记录之按照频率将数组升序排序

/**
 * 给你一个整数数组 nums ,请你将数组按照每个值的频率 升序 排序。
 * 如果有多个值的频率相同,请你按照数值本身将它们 降序 排序。 
 * 请你返回排序后的数组。
 * 
 * 示例1:
 * 输入:nums = [1,1,2,2,2,3]
 * 输出:[3,1,1,2,2,2]
 * 解释:'3' 频率为 1,'1' 频率为 2,'2' 频率为 3 。
 * 
 * 示例2:
 * 输入:nums = [2,3,1,3,2]
 * 输出:[1,3,3,2,2]
 * 解释:'2' 和 '3' 频率都为 2 ,所以它们之间按照数值本身降序排序。
 * 
 * 提示:
 * 1 <= nums.length <= 100
 * -100 <= nums[i] <= 100
 * 
 * 解题思路:
 * 1.通过题目我们可以大致有一个思路,我们需要比较2个部分:首先是频率升序,如果频率相同时按照数值本身降序排序(频率优先级更高)。
 * 2.既然需要排序,那么我们很容易想到数组排序,如何造一个数组使其即可以同时试下1的两类排序呢?
 * 3.我们可以造一个数字同时可以体现nums对应位置上的频率及数值本身的值,使其可以通过一次排序得到我们想要的结果。
 *     如:
 *        nums = [2,3,1,3,2]  => 转换后nums = [2002,2003,1001,2003,2002] 
 *         nums[0]:2出现了2次,那我们可以使用2002
 *         nums[1]:3出现了2次,那我们可以使用2003
 *         nums[2]:1出现了1次,那我们可以使用1001
 *         nums[3]:3出现了2次,那我们可以使用2003
 *         nums[4]:2出现了2次,那我们可以使用2002
 *         将转换后nums进行升序排序:频率优先 转换后nums从小到大排序后:转换后nums [1001,2002,2002,2003,2003] =>还原后nums [1,2,2,3,3]
 *         得到的结果有个问题:就是不满足条件2(如果频率相同时按照数值本身降序排序)
 * 
 *      ★我们可以换个思路由于-100 <= nums[i] <= 100,我们可以用原值与100的差值作为后三位去进行升序排序,这样去掉频率位后就相当于原值降序排序。
 *        nums = [2,3,1,3,2]  => 转换后nums = [2098,2097,1099,2097,2098]
 *         nums[0]:2出现了2次,那我们可以使用2098
 *         nums[1]:3出现了2次,那我们可以使用2097
 *         nums[2]:1出现了1次,那我们可以使用1099
 *         nums[3]:3出现了2次,那我们可以使用2097
 *         nums[4]:2出现了2次,那我们可以使用2098
 *         将转换后nums进行升序排序:频率优先转换后nums从小到大排序后:转换后nums [1099,2097,2097,2098,2098] => 还原后nums[1,3,3,2,2] 
 *         结果同时满足频率相同时按照数值本身降序排序√ 完成
 *  4.按照如下步骤完成上述思想:求原值对应频率=>转换nums数组=>排序=>还原数据
 *      · 由于提示给出的边界,我们可以造一个length为201的每一个元素都为0的数组(arr=new Array(201).fill(0))
 *      · 求原值对应频率:遍历nums,arr[nums[i] + 100]++ ,这样下标反应原值,对应值代表频次
 *      · 转换nums数组:
 *              遍历nums, 现有频次:arr[nums[i] + 100],原值:nums[i],原值与100取反:100-nums[i];
 *              nums每一项值转换规则:arr[nums[i] + 100]*1000 + (100-nums[i])
 *      · 排序: nums.sort((a,b)=>a-b);
 *      · 还原数据:遍历nums,去除频次:nums[i]%1000;  即对应原值规则: 100 - nums[i]%1000;
 *  5.nums即为符合条件的返回值          
 */
/**
 * @param {number[]} nums
 * @return {number[]}
 */
var frequencySort = function(nums) {
    var arr = new Array(201).fill(0),n=nums.length;
    for (let i = 0; i < n; i++){
        arr[nums[i] + 100]++;
    }
    for (let i = 0; i < n; i++){
        nums[i] = arr[nums[i] + 100] * 1000 + (100 - nums[i]);
    }
    nums.sort((a,b)=>a-b);
    for (let i = 0; i < n; i++){
        nums[i] = 100 - nums[i] % 1000;
    }
    return nums;
};

var nums = [2,3,1,3,2];
console.log(frequencySort(nums));

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值