leetcode 761. 特殊的二进制字符串 困难

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

  • 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 是一个特殊的二进制字符串。

分析:可以将 1 看作 (,将 0 看作 ),问题就转化为了左右括号匹配。

合法括号字符串满足:左右括号的个数相等;每个右括号,都在左边有与之匹配的左括号。这意味着,对于括号字符串的每个前缀,左括号的个数不能低于右括号的个数(否则右括号无法找到配对的左括号)。移动操作可看作选择 s 中的一对相邻的合法括号子串,再交换。

合法括号字符串有两种组合方式:

拼接。如 ()+(())=()(())。多个合法括号字符串拼接在一起,可以得到更长的合法括号字符串。
嵌套。如 (+()()+)=(()())。在合法括号字符串的外层套一对括号,可以得到更长的合法括号字符串。

对于拼接,把 s 拆分成若干个更短的合法括号子串,这些子串都可以做相邻交换。可以把这些子串按照字典序从大到小排序。

对于嵌套,去掉外层的一对括号,问题变成操作子串 [1,n−2] 能得到的最大字典序。这是一个规模更小(长为 n−2)的子问题,可以递归解决。

cpp 复制代码
class Solution {
public:
    string makeLargestSpecial(string s) {
        if(s.size()<=2)return s;

        vector<string>substring;
        int cnt=0,index=0;
        for(int i=0;i<s.size();++i)
        {
            if(s[i]=='1')cnt++;
            else if(--cnt==0)
            {
                substring.push_back("1"+makeLargestSpecial(s.substr(index+1,i-index-1))+"0");
                index=i+1;
            }
        }
        sort(substring.begin(),substring.end());
        string ret="";
        for(int i=substring.size()-1;i>=0;--i)
            ret+=substring[i];
        return ret;
    }
};
相关推荐
6Hzlia2 小时前
【Hot 100 刷题计划】 LeetCode 189. 轮转数组 | C++ 三次反转经典魔法 (O(1) 空间)
c++·算法·leetcode
m0_629494732 小时前
LeetCode 热题 100-----13.最大子数组和
数据结构·算法·leetcode
田梓燊3 小时前
力扣:94.二叉树的中序遍历
数据结构·算法·leetcode
khalil10203 小时前
代码随想录算法训练营Day-38动态规划06 | 322. 零钱兑换、279.完全平方数、139.单词拆分、多重背包、总结
数据结构·c++·算法·leetcode·动态规划
阿Y加油吧3 小时前
二刷 LeetCode:300. 最长递增子序列 & 152. 乘积最大子数组 复盘笔记
笔记·算法·leetcode
6Hzlia3 小时前
Hot 100 刷题计划】 LeetCode 146. LRU 缓存 | C++ 哈希表+双向链表
c++·leetcode·缓存
我不是懒洋洋3 小时前
【数据结构】二叉树OJ(单值二叉树、检查两棵树是否相同、对称二叉树、二叉树的前序遍历、另一颗树的子树)
c语言·数据结构·c++·经验分享·算法·leetcode·visual studio
阿Y加油吧3 小时前
二刷 LeetCode:5. 最长回文子串 & 1143. 最长公共子序列 复盘笔记
笔记·算法·leetcode
小雅痞5 小时前
[Java][Leetcode middle] 167. 两数之和 II - 输入有序数组
java·算法·leetcode
xin_nai6 小时前
LeetCode热题100(Java)(6)矩阵
java·leetcode·矩阵