美文网首页
Reorganize String

Reorganize String

作者: nafoahnaw | 来源:发表于2018-03-20 18:38 被阅读0次

    Given a string S, check if the letters can be rearranged so that two characters that are adjacent to each other are not the same.

    If possible, output any possible result. If not possible, return the empty string.

    Example 1:

    Input: S = "aab"
    Output: "aba"
    Example 2:

    Input: S = "aaab"
    Output: ""
    Note:

    S will consist of lowercase letters and have length in range [1, 500].

    大意就是把给出的字符串重新排序,转换成相邻字符都不相同的字符串,如果没有结果则返回空字符串

       /**
         * 通过这样一个结论:
         * 对于一个排好序的字符数组,如果我们交叉放置,即先从下标1开始放置,步长=2
         * ,放置完毕后,再从下标0开始,步长=2放置
         * 大概就像这样S[3], S[0], S[4], S[1], S[5], S[2]
         * 这样的话确保了相邻的原本相邻的字符都被打乱,满足了题目的要求
         *
         * @param s
         * @return
         */
        public String reorganizeString(String s) {
            int[] _26char = new int[26];
            /**
             * 经过以下两步之后s中的每个字符都会以数字的形式展示
             * _26char[i] % 100表示该字符对于'a'的偏移量
             * _26char[i] / 100表示该字符在s中出现的次数
             */
            for(char c : s.toCharArray()){
                _26char[c - 'a'] += 100;
            }
            for(int i = 0; i < 26; i++){
                _26char[i] += i;
            }
            /**
             * 排序是为了把出现次数最多的字母放在数组的最后
             * aab->baa
             * 为什么要这么做?
             * 考虑给出字符是aab的情况,交叉放置的话结果还是aab
             * 但是如果是baa的情况,交叉放置的结果就是aba
             */
            Arrays.sort(_26char);
    
            char[] result = new char[s.length()];
            int t = 1;
            for(int i = 0; i < _26char.length; i++){
                int ct = _26char[i] / 100;
                char ch = (char)(_26char[i] % 100 + 'a');
                /**
                 * 快速失败条件
                 * 当一个字符出现的次数超过给出字符串的长度的一半的话,那么是不可能有答案的
                 * 长度为ct的重复字符串至少需要ct-1长度的其他字符串才能变为不重复的字符串,
                 * 那么字符串的总长度至少是2ct-1,由此可以推出2ct-1大于给出字符串的长度则必不会成功
                 */
                if(ct > (s.length() + 1)/2){
                    return "";
                }
                for(int j = 0; j < ct; j++){
                    //如果t超过了s下标边界则重置为0,从0开始填充
                    if(t > s.length()-1){
                        t = 0;
                    }
                    result[t] = ch;
                    t += 2;
                }
            }
    
            return String.valueOf(result);
        }
    

    相关文章

      网友评论

          本文标题:Reorganize String

          本文链接:https://www.haomeiwen.com/subject/mgnbqftx.html