豆包 力扣 761. 特殊的二进制字符串 public String makeLargestSpecial(String s)

📅 发布时间:2026/7/7 20:25:18 👁️ 浏览次数:
豆包 力扣 761. 特殊的二进制字符串 public String makeLargestSpecial(String s)
你想要解决力扣 761 题「特殊的二进制字符串」核心需求是找到给定特殊二进制字符串能重排得到的最大字典序字符串。问题背景与解题思路首先明确特殊的二进制字符串定义前缀中 ‘1’ 的数量始终不少于 ‘0’ 的数量整个字符串中 ‘1’ 和 ‘0’ 的数量相等。解题核心思路分治 贪心拆分将原字符串拆分为若干个不可再分的「最小特殊二进制子串」形如1...0且内部无法再拆分为更小的特殊子串递归处理对每个最小特殊子串的内部去掉首尾的 1 和 0 后递归处理保证内部也是最大字典序排序拼接将所有处理后的最小特殊子串按字典序降序排列拼接后即为结果。完整可运行代码classSolution{publicStringmakeLargestSpecial(Strings){// 递归终止条件空字符串或长度为0直接返回if(snull||s.length()0){return;}// 存储拆分后的最小特殊二进制子串ListStringpartsnewArrayList();// 记录当前前缀中1的数量 - 0的数量平衡值intbalance0;// 记录每个最小特殊子串的起始位置intstart0;for(inti0;is.length();i){// 遇到1平衡值1遇到0平衡值-1balances.charAt(i)1?1:-1;// 当平衡值回到0时说明找到了一个最小特殊子串 [start, i]if(balance0){// 对该子串的内部去掉首尾的1和0递归处理再拼接首尾Stringsub1makeLargestSpecial(s.substring(start1,i))0;parts.add(sub);// 更新下一个子串的起始位置starti1;}}// 将拆分后的子串按字典序降序排列贪心大的子串放前面整体字典序最大Collections.sort(parts,Collections.reverseOrder());// 拼接所有排序后的子串得到最终结果StringBuildersbnewStringBuilder();for(Stringpart:parts){sb.append(part);}returnsb.toString();}}代码关键部分解释平衡值balance遍历字符串时遇到 ‘1’ 加 1遇到 ‘0’ 减 1当balance 0时说明从start到当前位置是一个最小特殊二进制子串无法再拆分为更小的特殊子串。递归处理子串内部对于找到的最小子串s[start..i]去掉首尾的 ‘1’ 和 ‘0’即s[start1..i-1]递归调用函数处理内部保证内部也是最大字典序处理后再拼接回首尾的 ‘1’ 和 ‘0’得到该子串的最大形式。贪心排序将所有处理后的最小子串按字典序降序排列拼接后整体字典序最大例如1100比1010字典序大应放在前面。示例验证输入s 11011000执行过程拆分得到最小子串1100、10递归处理内部无需要处理得到[1100, 10]降序排序后为[1100, 10]拼接结果为110010正确答案。总结核心逻辑是分治 贪心将字符串拆分为最小特殊子串递归优化内部再按字典序降序拼接平衡值是拆分最小特殊子串的关键balance 0是拆分节点贪心排序保证了整体字典序最大符合题目要求。该解法时间复杂度主要由排序决定假设拆分出 k 个子串排序复杂度为 O(k log k)空间复杂度为递归栈和存储子串的空间是力扣该题的最优解法之一。