LeetCode 761.特殊的二进制字符串:分治(左右括号对移动)

【LetMeFly】761.特殊的二进制字符串:分治(左右括号对移动)

力扣题目链接:https://leetcode.cn/problems/special-binary-string/

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

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

给定一个特殊的二进制字符串 s

一次移动操作包括选择字符串 s 中的两个连续的、非空的、特殊子串,并交换它们。两个字符串是连续的,如果第一个字符串的最后一个字符与第二个字符串的第一个字符的索引相差正好为 1。

返回在字符串上应用任意次操作后可能得到的字典序最大的字符串。

示例 1:

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

示例 2:

复制代码
输入:s = "10"
输出:"10"

提示:

  • 1 <= s.length <= 50
  • s[i]'0''1'
  • s 是一个特殊的二进制字符串。

解题方法:分治

例如示例一:11011000,可以看成(()(()))

我们要做的就是保持括号处于匹配状态下,让对应的01字符串字典序尽可能大。

匹配字符串有两种组合方式:

  1. 拼接,如() + (()) = ()(())
  2. 嵌套,在()(())外面套一个括号变成(()(()))

这解法不就来了,我们可以反其道而行之,把``(()(()))拆成( () (()) )`:

对于最外层括号里的()(()),当然是(())放到()前面比较好(1100放到10前面字典序更大)

这不就是天然的递归么,(()(()))只有一个"拼接的括号",外层总体顺序不变,内层()(())递归:

内层()(())有两个"拼接的括号",两个拼接的括号分别递归,直到递归字符串为空递归停止,并将两个递归完成的"拼接括号"排序重新拼接到一起,变成(())()

  • 时间复杂度 O ( n 2 log ⁡ n ) O(n^2\log n) O(n2logn),递归像树一样,每次执行有一个排序和字符串拼接

    复制代码
    (()(()))
       |
     ()(())
     /    \
    ''    ()
  • 空间复杂度 O ( n ) O(n) O(n)

AC代码

C++
cpp 复制代码
/*
 * @LastEditTime: 2026-02-20 11:21:04
 */
/*
11011000
(()(()))
(  ()   (())    )
*/
class Solution {
private:
    vector<pair<int, int>> split(string& s) {
        vector<pair<int, int>> ans;
        int diff = 0, from = 0;
        for (int i = 0; i < s.size(); i++) {
            if (s[i] == '1') {
                diff++;
            } else {
                diff--;
            }
            if (!diff) {
                ans.push_back({from, i});
                from = i + 1;
            }
        }
        return ans;
    }
public:
    string makeLargestSpecial(string s) {
        if (s.empty()) {
            return s;
        }
        vector<pair<int, int>> pairs = split(s);
        vector<string> parts;
        parts.reserve(pairs.size());
        for (auto [l, r] : pairs) {
            parts.push_back('1' + makeLargestSpecial(s.substr(l + 1, r - l - 1)) + '0');
        }
        sort(parts.begin(), parts.end(), greater<>());
        string ans;
        for (string& part : parts) {
            ans += part;
        }
        return ans;
    }
};

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

千篇源码题解已开源

相关推荐
小O的算法实验室1 小时前
2025年AEI SCI1区TOP,面向城市区域监视的任务驱动多无人机路径规划三阶段优化策略,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
癫狂的兔子1 小时前
【Python】【机器学习】集成算法(随机森林、提升算法)
python·算法·机器学习
小龙报2 小时前
【算法通关指南:数据结构与算法篇】二叉树相关算法题:1.二叉树深度 2.求先序排列
c语言·开发语言·数据结构·c++·算法·贪心算法·动态规划
吾在学习路2 小时前
AoP-SAM: Automation of Prompts for Efficient Segmentation
人工智能·深度学习·算法·计算机视觉
再难也得平2 小时前
[LeetCode刷题]1.两数之和(java题解)
java·算法·leetcode
踩坑记录2 小时前
leetcode hot100 39. 组合总和 medium 递归回溯
leetcode
皮卡蛋炒饭.2 小时前
钻石收集者&是7倍数的最长子序列&Zuma
数据结构·算法·排序算法
plus4s2 小时前
2月20日(88-90题)
算法
仰泳的熊猫2 小时前
题目1529:蓝桥杯算法提高VIP-摆花
数据结构·c++·算法·蓝桥杯