力扣:767. 重构字符串

本文介绍了一种使用贪心算法和优先队列解决字符串重构问题的方法。通过统计字符出现次数并判断重构可能性,优先队列确保了最大频率字符的优先处理,实现了字符串的重新排列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个使用到了贪心算法,使用优先队列来进行添加字符串。

方法:

  1. 如果字符串小于二那没有意思,直接退出。
  2. 创建一个数组记录所有的字母。
  3. 把出现的次数进行统计,如果最大出现的单词大于数组长度的一半,那么是不可能重构的。
  4. 创建优先队列,队列的栈顶就是出现最多次数的字母。
  5. 把字母加入队列,然后进行取值。

 



import java.util.Comparator;
import java.util.PriorityQueue;

/**
 * @author xnl
 * @Description:
 * @date: 2022/6/6   22:52
 */
public class Solution {
    public static void main(String[] args) {
        Solution solution = new Solution();
        String str = "zhmyo";
        System.out.println(solution.reorganizeString(str));
    }

    public String reorganizeString(String s) {
        // 如果小于二的话,没有重构的必要了
        if (s.length() < 2){
            return "";
        }
        // 存放26个单词
        int[] counts = new int[26];
        int maxCount = 0;
        // 把所有出现的单词进行统计,放到数组中去
        for (int i = 0; i < s.length(); i++){
            char c = s.charAt(i);
            counts[c - 'a']++;
            maxCount = Math.max(maxCount, counts[c - 'a']);
        }
        if (maxCount > (s.length() + 1) / 2){
            return "";
        }

        // 优先队列,贪心就贪心在这里,栈顶取最大出现的数
        PriorityQueue<Character> queue = new PriorityQueue<Character>(new Comparator<Character>() {
            @Override
            public int compare(Character o1, Character o2) {
                return counts[o2 - 'a'] - counts[o1 - 'a'];
            }
        });

        // 出现的字符进行入栈
        for (char i = 'a'; i <= 'z'; i++){
            if (counts[i - 'a'] > 0){
                queue.offer(i);
            }
        }

        StringBuilder sb = new StringBuilder();
        while (queue.size() > 1){
            Character poll1 = queue.poll();
            Character poll2 = queue.poll();
            sb.append(poll1);
            sb.append(poll2);
            // 两个单词对应的下标
            int index1 = poll1 - 'a', index2 = poll2 - 'a';
            // 值取出来了,对应数组的值就需要减一
            counts[index1]--;
            counts[index2]--;
            if (counts[index1] > 0){
                queue.offer(poll1);
            }

            if (counts[index2] > 0){
                queue.offer(poll2);
            }
        }
        if (queue.size() > 0){
            sb.append(queue.poll());
        }
        return sb.toString();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值