zoukankan      html  css  js  c++  java
  • 算法——重构字符串使得相邻字符不同

    给定一个字符串S,检查是否能重新排布其中的字母,使得两相邻的字符不同。
    若可行,输出任意可行的结果。若不可行,返回空字符串。
    leetcode

    解题思路:

    • 首先想想什么样的情况下不能构成可行的字符串,就像植树问题,最大的相同的字符个数一定小于字符串长度加一再除以二,如果超了就肯定会相邻。
    • 所以,我们在枚举输出的时候,只要剩下需要输出的字符串一直满足这个条件,就一直能够产生合法的答案。当我们每次输出数量最大的两个字符串的时候,就能够让原来的字符串一直满足条件了。你想嘛,如果每次都输出数量的了,那么数量大的不就肯定会超过半数了。
      这里利用了优先队列,让数量多的字符排在对头。
    class Solution {
        public String reorganizeString(String s) {
            int n = s.length();
            if(n < 2) return s;
    
    		// 通过数组对字符串的字符进行计数
            int[] cnt = new int[26];
            int maxCnt = 0;
            for(char c : s.toCharArray()) {
                cnt[c - 'a'] ++;
            }
    
            for(int i : cnt) {
                maxCnt = Math.max(maxCnt, i);
            }
    
            if(maxCnt > (n + 1) / 2) return "";
    		
    		// 构造优先队列
            PriorityQueue<Character> q = new PriorityQueue<>((a, b) -> cnt[b - 'a'] - cnt[a - 'a']);
    
    		// 填入优先队列
            for(int i = 0; i < 26; i++) {
                if(cnt[i] > 0) q.offer((char)(i + 'a'));
            }
    
            StringBuilder res = new StringBuilder();
    
            while(q.size() > 1) {
            	// 每次提取两个数量最多的字符
                char a = q.poll();
                char b = q.poll();
                res.append(a);
                res.append(b);
    
                cnt[a - 'a'] --;
                cnt[b - 'a'] --;
                if(cnt[a - 'a'] > 0) q.offer(a);
                if(cnt[b - 'a'] > 0) q.offer(b);
            }
    
    		// 最后可能还剩下一个
            if(q.size() > 0) res.append(q.poll());
    
            return res.toString();
        }
    }
    
  • 相关阅读:
    jQuery return false
    js获取拼音
    jQuery.getScript加载同域JS
    清除浮动,clearfix的bug
    chrome本地文件加载跨域请求
    中间容器宽度自适应的三栏布局
    mac安装nginx
    弹出一次“设为主页”和“加入收藏”代码
    未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序
    IIS7/IIS7.5下轻松配置PHP利器(微软PHP Manager for IIS 7)
  • 原文地址:https://www.cnblogs.com/lippon/p/14117607.html
Copyright © 2011-2022 走看看