loading

力扣每日一题 761. 特殊的二进制序列

特殊的二进制序列是具有以下两个性质的二进制序列:

  • 0 的数量与 1 的数量相等。
  • 二进制序列的每一个前缀码中 1 的数量要大于等于 0 的数量。

给定一个特殊的二进制序列 S,以字符串形式表示。定义一个操作 为首先选择 S 的两个连续且非空的特殊的子串,然后将它们交换。(两个子串为连续的当且仅当第一个子串的最后一个字符恰好为第二个子串的第一个字符的前一个字符。)

在任意次数的操作之后,交换后的字符串按照字典序排列的最大的结果是什么?

示例 1:

输入: S = "11011000"
输出: "11100100"
解释:
将子串 "10" (在S[1]出现) 和 "1100" (在S[3]出现)进行交换。
这是在进行若干次操作后按字典序排列最大的结果。

说明:

  1. S 的长度不超过 50
  2. S 保证为一个满足上述定义的特殊 的二进制序列。
Related Topics
  • 递归
  • 字符串

  • 👍 166
  • 👎 0
  • 这道题自己没有做出来,借鉴了大佬的思路。反复debug弄明白了解题的巧妙之处。
    核心思路为:

    1. 保证成对出现,有一个1必须要有一个0。
    2. 基于递归的思路,不停将复杂的字符串,拆分为”10“,本题中的”10“和”1100“都是被细分为了”10“进行求解

    代码如下

    package editor.cn;
    
    
    //leetcode submit region begin(Prohibit modification and deletion)
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    /**
     * @description: 761 特殊的二进制序列
     * @author: ShaoYJ
     * @date: 2022/8/8 18:52
     */
    class Q761 {
        /**
         * 0 的数量与 1 的数量相等。
         * 二进制序列的每一个前缀码中 1 的数量要大于等于 0 的数量。
         *
         * @param s 满足特殊的二进制序列
         * @return 新的字符串
         */
        public String makeLargestSpecial(String s) {
            List<String> candidates = new ArrayList<>();
            for (int i = 0, cur = 0, last = 0, n = s.length(); i < n; i++) {
                cur += s.charAt(i) == '1' ? 1 : -1;
                if (cur == 0) {
    //                将能满足cur为0的中间的子字符串(last+1,i)给函数 ,得到的结果格式化为  ”1str0“
                    candidates.add(String.format("1%s0", makeLargestSpecial(s.substring(last + 1, i))));
                    last = i + 1;
                }
            }
            StringBuilder sb = new StringBuilder();
            Collections.sort(candidates, (a, b) -> b.compareTo(a));
            for (String str: candidates) {
                sb.append(str);
            }
            return sb.toString();
        }
    
        public String makeLargestSpecial2(String s) {
            List<String> res = new ArrayList<>();
    
            int cnt = 0;
            int pre = 0;
            for(int i =0;i<s.length();i++){
                int tmp = s.charAt(i)=='1'?1:-1;
                cnt+=tmp;
    
                /*
                   当满足等于0的时候,该部分字符串 必定是以 ”1“+str+"0"构成
                   1. 将自己加入res
                   2. 将自己的去头去尾的子字符串再递归给函数,找到更小的满足条件的子字符串
                 */
                if(cnt==0){
                    String subStr = s.substring(pre+1,i);
                    res.add(String.format("1%s0", makeLargestSpecial2(subStr)));
                    // 将pre更新为新的i+1,预备给可能的下一个字符串
                    pre = i+1;
                }
            }
            // 对res进行字典排序,基于集合工具类
            Collections.sort(res,(a,b)-> b.compareTo(a));
            StringBuffer sb = new StringBuffer();
            // 拼接字符串
            for (String str : res) {
                sb.append(str);
            }
    
            return sb.toString();
        }
    
    
        public static void main(String[] args) {
            String S = "11011000";
            Q761 q761 = new Q761();
            System.out.println(q761.makeLargestSpecial2(S));
        }
    }
    //leetcode submit region end(Prohibit modification and deletion)
    
    

    结果截图

    posted @ 2022-08-09 10:54  EaApple  阅读(37)  评论(0)    收藏  举报