leetcode 767. Reorganize String(重组字符串)

重新排列字符串s中的字母,使得任意两个相邻的字母都不相同。

思路:

让相邻字母不同,能想到的办法是先把相同的字母排列,

然后在相同字母的缝隙中插入另一种字母。

比如"aab", 先把"a a"排出来,再在2个a的缝隙中插入b,得到"aba".

那么就需要统计每个字母出现的次数。

为了让能插入字母的缝隙,排列时中间空一位,也就是先把出现最多的字母放在偶数位,

如果不够放就折回来到奇数位,所以字母出现次数不能超过s长度的一半,

不然折回来就是相同字母了。字母的出现次数超过s一半的直接返回""。

而且一定要先排出现最多的字母(可以试试example1中先排b)。

可以用一个优先队列按字母出现的次数从大到小排列。然后一一取出排列。

也可以只找到出现次数最多的字母,先排列,再直接按顺序排剩下的。

优先队列:

java 复制代码
    public String reorganizeString(String s) {
        HashMap<Character,Integer> map = new HashMap<>();
        char[] chs = s.toCharArray();
        //按字母出现的次数倒序排列
        PriorityQueue<Character> pq = new PriorityQueue<>((a,b)->(map.get(b)-map.get(a)));
        char[] res = new char[s.length()];

        for(char c : chs) {
            map.put(c, map.getOrDefault(c, 0)+1);
        }
        pq.addAll(map.keySet());

        //出现频率最多的字母多于字符串长度的一半
        if(map.get(pq.peek()) > (s.length()+1)/2) return "";
        
        int i = 0;

        while(!pq.isEmpty()) {
            char c = pq.poll();
            for(int j = 0; j < map.get(c); j++) {
                if(i >= s.length()) i = 1;  //偶数位放满,开始放奇数位
                res[i] = c;
                i += 2;
            }
        }
        return new String(res);
    }

只先排出现次数最多的,剩下的按顺序排。此方法更快。

java 复制代码
    public String reorganizeString(String s) {
        int[] cnt = new int[26];
        char[] chs = s.toCharArray();
        int n = chs.length;
        char[] res = new char[n];

        for(int i = 0; i < n; i++) cnt[chs[i]-'a']++;

        //找到出现次数最多的字母和次数
        int maxCnt = 0;
        int freqCh = 0;
        for(int i = 0; i < 26; i++) {
            if(cnt[i] > maxCnt) {
                maxCnt = cnt[i];
                freqCh = i;
            }
        }

        if(maxCnt > (n+1)/2) return "";
        //先排出现最多的字母,不然可能会出现奇数位和偶数位是同一字母的情况
        int idx = 0;
        while(cnt[freqCh] > 0) {
            res[idx] = (char)(freqCh + 'a');
            idx += 2;
            cnt[freqCh] --;
        }

        for(int i = 0; i < 26; i++) {
            while(cnt[i] > 0) {
                if(idx >= n) idx = 1;
                res[idx] = (char)(i+'a');
                idx += 2;
                cnt[i] --;
            }
        }
        return new String(res);
    }
相关推荐
2501_941875281 天前
从数据库写入拥堵到分布式写入优化与多语言实践落地的互联网系统工程随笔
leetcode·散列表·模拟退火算法
CodeAllen嵌入式1 天前
嵌入式C/C++:栈与堆内存管理
java·c语言·c++
sin_hielo1 天前
leetcode 1390
数据结构·算法·leetcode
.小墨迹1 天前
VMware使用问题汇总
linux·网络·学习·算法
毕设源码-钟学长1 天前
【开题答辩全过程】以 基于springboot的健身房ERP系统设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
To Be Clean Coder1 天前
【Spring源码】getBean源码实战(七)——BeanPostProcessor与初始化方法
java·后端·spring
+VX:Fegn08951 天前
计算机毕业设计|基于springboot + vue民宿平台管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·课程设计
窗边鸟1 天前
小白日记之Java循环结构
java
毕设源码-赖学姐1 天前
【开题答辩全过程】以 高校教学管理系统的设计与实现为例,包含答辩的问题和答案
java
xl.liu1 天前
GN(Girvan-Newman)算法详解:从原理到实现及其在商品关联集合分析中的应用
开发语言·算法·php