761. Special Binary String

Special binary strings are binary strings with the following two properties:

The number of 0’s is equal to the number of 1’s.
Every prefix of the binary string has at least as many 1’s as 0’s.
Given a special string S, a move consists of choosing two consecutive, non-empty, special substrings of S, and swapping them. (Two strings are consecutive if the last character of the first string is exactly one index before the first character of the second string.)

At the end of any number of moves, what is the lexicographically largest resulting string possible?

Example 1:

Input: S = "11011000"
Output: "11100100"
Explanation:
The strings "10" [occuring at S[1]] and "1100" [at S[3]] are swapped.
This is the lexicographically largest string possible after some number of swaps.

Note:

S has length at most 50.
S is guaranteed to be a special binary string as defined above.

思路:
按照special binary string的定义,首字母一定是”1”,末尾一定是”0”,这两位是我们无法改变的,所以我们完全可以求解子问题:除了首尾的字符串。各位且慢,举个例子”1010”,是special binary string,首尾的确分别是1和0,但很遗憾”01”并不是special binary string啊,那怎么用递归解决啊!所以我们需要确保找到”1A….B0”之后,”A…B”也是special binary string。 很简单,只要第一次出现count == 0的字符串。它除了首尾的子串一定是special binary string。证明:因为”1A….CB0” count = 0,所以,”1A….CB”时,count = 1,如果”B = 1”,只能为”1A…C” ,count = 0,这就提前出现了count = 0的情况,吼吼,与假设矛盾。
能够找到第一个count = 0的special binary string,并且确保了子问题也是special binary string,就可以递归求解了。不过,最终还需要输出lexicographically,所以排个序再合并之前分解的special binary string.

class Solution {
    public String makeLargestSpecial(String S) {
        int count = 0, i = 0;
        List<String> res = new ArrayList<String>();
        for (int j = 0; j < S.length(); ++j) {
          if (S.charAt(j) == '1') count++;
          else count--;
          if (count == 0) {
            res.add('1' + makeLargestSpecial(S.substring(i + 1, j)) + '0');
            i = j + 1;
          }
        }
        Collections.sort(res, Collections.reverseOrder());
        return String.join("", res);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值