lc358: K 距离间隔重排字符串

题目:

给你一个非空的字符串 s 和一个整数 k,你要将这个字符串中的字母进行重新排列,使得重排后的字符串中相同字母的位置间隔距离至少为 k。

所有输入的字符串都由小写字母组成,如果找不到距离至少为 k 的重排结果,请返回一个空字符串 ""。

示例 1:

输入: s = "aabbcc", k = 3
输出: "abcabc" 
解释: 相同的字母在新的字符串中间隔至少 3 个单位距离。
示例 2:

输入: s = "aaabc", k = 3
输出: "" 
解释: 没有办法找到可能的重排结果。
示例 3:

输入: s = "aaadbbcc", k = 2
输出: "abacabcd"
解释: 相同的字母在新的字符串中间隔至少 2 个单位距离。

解答:

贪心法,每次尽量取频次大的字母加入结果。

先统计每个字母出现的次数,存入map

然后把所有的[字母:频次]存入最大堆

每次从最大堆中取k个最大频次的字母,加入结果字符串。然后相应频次减一后再放回最大堆。

最终要么堆为空,则成功。如果堆中剩下不到k个字母,那么只能取一次(即字符串结尾,因为后面没有其他元素了),否则失败。

public static String getResult(String s,int k){

        if(k<2)return s;
        //记录小写字母出现的次数
        int[] alph = new int[26];
        for(char c:s.toCharArray())
            alph[c-'a']++;
        //构建大顶堆,根据字母出现次数的大小的顺序排序,且相同次数以字母表排序,并添加
        PriorityQueue<Character> pq = new PriorityQueue<>((a,b)->{
            if(alph[a-'a']!=alph[b-'a'])return Integer.compare(alph[b-'a'],alph[a-'a']);
            return Character.compare(a,b);
        });
        for(char z ='a';z<='z';z++){
            if(alph[z-'a']>0){
                pq.add(z);
            }
        }

        StringBuffer sb = new StringBuffer();

        List<Character> list = new ArrayList<>();

        int len = s.length();
        while(!pq.isEmpty()){
            //计算每一块的长度,避免最后剩余部分的长度小于k
            k=Math.min(k,len);
            for(int i =0;i<k;i++){
                if(!pq.isEmpty()){
                    char c = pq.poll();
                    sb.append(c);
                    len--;
                    alph[c-'a']--;
                    //记录弹出的次数不为0的字母
                    if(alph[c-'a']>0)
                        list.add(c);
                }else return "";
            }
            //将不为零的字母加入到大顶堆中
            pq.addAll(list);
            list.clear();
        }
        
        return sb.toString();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值