特殊的二进制序列是具有以下两个性质的二进制序列:
0 的数量与 1 的数量相等。
二进制序列的每一个前缀码中 1 的数量要大于等于 0 的数量。
给定一个特殊的二进制序列 S,以字符串形式表示。定义一个操作 为首先选择 S 的两个连续且非空的特殊的子串,然后将它们交换。(两个子串为连续的当且仅当第一个子串的最后一个字符恰好为第二个子串的第一个字符的前一个字符。)
在任意次数的操作之后,交换后的字符串按照字典序排列的最大的结果是什么?
示例 1:
输入: S = "11011000"
输出: "11100100"
解释:
将子串 "10" (在S[1]出现) 和 "1100" (在S[3]出现)进行交换。
这是在进行若干次操作后按字典序排列最大的结果。
说明:
S 的长度不超过 50。
S 保证为一个满足上述定义的特殊 的二进制序列。
思路:我用的分治法。比较暴力,算是卡时间过的。。。
class Solution {
Map<String,String> map=new HashMap<>();
public String makeLargestSpecial(String S) {
if(S.length()<=2) return S;
if(map.containsKey(S))
return map.get(S);
StringBuilder str=new StringBuilder();
StringBuilder sss=new StringBuilder();
StringBuilder last=new StringBuilder();
str.append(S);
while(!str.toString().equals(last.toString())) {
last.delete(0, last.length());
last.append(str);
for(int i=1;i<S.length();i++) {
sss.delete(0, sss.length());
sss.append(makeLargestSpecial(str.substring(0, i)));
sss.append(makeLargestSpecial(str.substring(i)));
if(sss.toString().compareTo(str.toString())>0) {
str.delete(0, str.length());
str.append(sss.toString());
}
}
}
for(int i=0;i<S.length();i++) {
if(Check(str.substring(0, i)) && Check(str.substring(i)) && jud(str.substring(0, i),str.substring(i))) {
sss.delete(0, sss.length());
sss.append(str.substring(i));
sss.append(str.substring(0, i));
if(sss.toString().compareTo(str.toString())>0) {
str.delete(0, str.length());
str.append(sss.toString());
}
}
}
map.put(S, str.toString());
return str.toString();
}
private boolean jud(String s1,String s2) {
String ss1=s1+s2;
String ss2=s2+s1;
return ss2.compareTo(ss1)>0;
}
private boolean Check(String s) {
int a=0,b=0;
for(int i=0;i<s.length();i++) {
if(s.charAt(i)=='1') a++;
else b++;
if(a<b) return false;
}
return a==b;
}
}