码迷,mamicode.com
首页 > 其他好文 > 详细

letcode每日一题-重构字符串

时间:2020-12-04 11:30:05      阅读:6      评论:0      收藏:0      [点我收藏+]

标签:last   操作   ast   情况   arc   动物   ring   最大堆   每日   

周末去了动物园,虽然我几乎被冻成了狗,但还是好开心呀,今天开开心心的来更新啦!!!
技术图片

题目描述:
技术图片
方法:基于最大堆的贪心算法
维护最大堆存储字母,堆顶元素为出现次数最多的字母。首先统计每个字母的出现次数,然后将出现次数大于 00 的字母加入最大堆。

当最大堆的元素个数大于 11 时,每次从最大堆取出两个字母,拼接到重构的字符串,然后将两个字母的出现次数分别减 11,并将剩余出现次数大于 00 的字母重新加入最大堆。由于最大堆中的元素都是不同的,因此取出的两个字母一定也是不同的,将两个不同的字母拼接到重构的字符串,可以确保相邻的字母都不相同。

如果最大堆变成空,则已经完成字符串的重构。如果最大堆剩下 11 个元素,则取出最后一个字母,拼接到重构的字符串。

对于长度为 nn 的字符串,共有 n/2n/2 次每次从最大堆取出两个字母的操作,当 nn 是奇数时,还有一次从最大堆取出一个字母的操作,因此重构的字符串的长度一定是 nn。

当 nn 是奇数时,是否可能出现重构的字符串的最后两个字母相同的情况?如果最后一个字母在整个字符串中至少出现了 22 次,则在最后一次从最大堆取出两个字母时,该字母会先被选出,因此不会成为重构的字符串的倒数第二个字母,也不可能出现重构的字符串最后两个字母相同的情况。

因此,在重构字符串可行的情况下,基于最大堆的贪心算法可以确保得到正确答案。
实现代码如下:


public String reorganizeString(String S) {
        int[] charCount=new int[26];
        //统计字符出现的次数
        for(int i=0;i<S.length();i++){
            int index=S.charAt(i)-‘a‘;
            charCount[index]++;
        }
        //创建一个从大到小排序的队列
        PriorityQueue<Character> queue=new PriorityQueue<>((o1,o2)->{
            if(charCount[o1-‘a‘]>charCount[o2-‘a‘]){
                return -1;
            }
            if(charCount[o1-‘a‘]<charCount[o2-‘a‘]){
                return 1;
            }
            return 0;
        });
        //把字符放进队列中
        for(int i=0;i<charCount.length;i++){
            if(charCount[i]!=0){
                queue.offer((char)(i+‘a‘));
            }
        }
        StringBuilder result=new StringBuilder();
        while (queue.size()>1){
            //出现频率最高的字符
            char max_count_char=queue.poll();
            //出现频率第二高的字符
            char second_count_char=queue.poll();
            int maxIndex=max_count_char-‘a‘;
            int secondIndex=second_count_char-‘a‘;
            //重新构建字符串
            if(result.length()==0 || result.charAt(result.length()-1)!=max_count_char){
                result.append(max_count_char);
                charCount[maxIndex]--;
            }
            int minLen=Math.min(charCount[maxIndex],charCount[secondIndex]);
            for(int i=0;i<minLen;i++){
                result.append(second_count_char).append(max_count_char);
            }
            //--重新构建字符串结束
            charCount[maxIndex]-=minLen;
            charCount[secondIndex]-=minLen;
            if(charCount[maxIndex]>0){
                queue.offer(max_count_char);
            }
            if (charCount[secondIndex]>0){
                queue.offer(second_count_char);
            }
        }
        if(queue.size()==0){
            return result.toString();
        }
        if(queue.size()==1){
            char last=queue.poll();
            if(charCount[last-‘a‘]==1 && result.charAt(result.length()-1)!=last){
                result.append(last);
                return result.toString();
            }
        }
        return "";
    }

letcode每日一题-重构字符串

标签:last   操作   ast   情况   arc   动物   ring   最大堆   每日   

原文地址:https://www.cnblogs.com/MissWX/p/14061399.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!