题目来源:https://leetcode.cn/problems/special-binary-string/
大致题意:
给定一个特殊的二进制字符串,该字符串需要满足以下条件:
该字符串可以分割成具有上述属性的子串,可以将不同的子串交换位置,最后返回满足条件的字典序最大的特殊字符串
对于长度为 2 的串,那么其字典序最大的特殊字符串为 10
对于长度为 4 的串,其字典序最大的特殊字符串为 1100,而这样的限制条件是原字符串本身即为 1100,若其为 1010,则只能交换其子串 10、10,无法变成 1100
举个例子,对于字符串 101100,其字典序最大的特殊字符串为 110010,其实就是分割成两个特殊子串 10 与 1100,然后将他们两个交换,具体操作时,即可以将当前字符串的特殊子串(此时假设该子串已经处理为字典序最大)放入集合中进行降序排序,最终拼接集合中的子串即为字典序最大的特殊子串
所以该题的解题思路可以概括为:
分割子串时,可以使用双指针遍历
代码:
class Solution {
public String makeLargestSpecial(String s) {
// 字符串小于等于 2,直接返回
if (s.length() <= 2) {
return s;
}
// 子串集合
List<String> subStr = new ArrayList<>();
int n = s.length();
// 左指针
int left = 0;
// 统计 1 和 0 出现的次数
int sum = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '1') {
sum++;
} else {
sum--;
}
// sum 为 0,表示左指针到当前位置出现的 1 和 0 数量相同,分割子串
if (sum == 0) {
// 分割并递归处理子串为字典序最大
subStr.add("1" + makeLargestSpecial(s.substring(left + 1, i)) + "0");
// 更新左指针
left = i + 1;
}
}
// 降序排序
Collections.sort(subStr, (a, b) -> b.compareTo(a));
StringBuffer sb = new StringBuffer();
// 拼接
for (String str : subStr) {
sb.append(str);
}
return sb.toString();
}
}