🌈【LeetCode 1647. 字符频次唯一的最小删除次数 】- JavaScript(哈希+排序)

82 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第10天,点击查看活动详情


说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)

作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金

GitHub:P-J27、 CSDN:PJ想做前端攻城狮

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


【LeetCode 1647. 字符频次唯一的最小删除次数 】- JavaScript(哈希+排序)

题意描述

如果字符串 s 中 不存在 两个不同字符 频次 相同的情况,就称 s 是 优质字符串 。

给你一个字符串 s,返回使 s 成为 优质字符串 需要删除的 最小 字符数。

字符串中字符的 频次 是该字符在字符串中的出现次数。例如,在字符串 "aab" 中,'a' 的频次是 2,而 'b' 的频次是 1 。

示例 1:

输入:s = "aab" 输出:0 解释:s 已经是优质字符串。

示例 2:

输入:s = "aaabbbcc" 输出:2 解释:可以删除两个 'b' , 得到优质字符串 "aaabcc" 。 另一种方式是删除一个 'b' 和一个 'c' ,得到优质字符串 "aaabbc" 。

思路分析:

我的主要思路还是统计 + 去重

核心在于:如何知道要删多少次 我们可以通过维护一个set,用来保存频率 比方说官方的第二个例子,3、3、2 当然,会有多种解法,3、1、2(删除中间的字母2个),或者3、2、1 但是不变的是删除的次数。

哈希~

哈希map,想都不用想,肯定要用上,多好用啊,直接让你离ac近了一半

具体:用字典统计所有字符出现的频率,将字典中的keys按照出现次数降序排列。遍历keys组成的列表,如果当前频率不小于上个频率,使用贪心思想删除当前字符

var minDeletions = function(s) {
    let map = new Map() ,arr = [] , res = 0
    for( let key of s ){
        map.set(key,(map.get(key) || 0) + 1)
    }
    for( let [key,value] of map ){
        if ( !arr[value] ) {
            arr[value] = 1
        }else {
            let can = 0 
            for( let i = value - 1 ; i ; i -- ){
                if ( !arr[i] && ( can = 1 , arr[i] = 1 ,res += value - i )) break
            }
            !can && ( res += value )
        }
    }
    return res
};

排序+模拟

思路:

这是一个我从别人那里看来的思路,可能效率不一定更好,但胜在代码少啊~又可以多摸会儿鱼了。

具体做事:先统计出现次数并降序,得到数组。再从数组第二个开始循环,比较与前一个值比较大小,如果大于等于前一个值且不为0,则增加一次“操作次数”,最终操作次数则为最少删除次数。

var minDeletions = function(s) {
    let charArr = new Array(26).fill(0);
    let arr = s.split('');
    arr.forEach((i)=>charArr[i.charCodeAt()-97]++);
    let resArr = charArr.filter((i)=>i>0).sort((a, b)=>b - a);
    let count = 0;
    for(let i = 1; i< resArr.length; i++){
        while(resArr[i] >= resArr[i-1] && resArr[i] > 0){
            resArr[i]--;
            count++;
        }
    }
    return count;
};

感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。

写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤