递归解

删括号

https://ac.nowcoder.com/acm/problem/21303

非曰能,好学。欢迎大家一起交流学习

题目描述

链接:https://ac.nowcoder.com/acm/problem/21303

给你一个合法的括号序列s1,每次你可以删除一个"()"
你可以删除0个或者多个"()"
求能否删成另一个括号序列s2

问题分析

看答案,大家都用的动态规划,这里提供一个递归解法。
括号可以批成一组一组的,如下图所示,s1被分为两组,s2只包括一组。

怎么分组呢?对字符串中的左括号右括号计数,相等的时候,即为一组的结束位置。为了使得s1能0个或者多个"()"变成s2,需要s1中从前往后去pk s2中的组,若是能pk过,则去pk下一组,类似于判定一个字符串是否为另一个字符串的子序列

那怎么判断s1中的一组括号能pk过s2中一组括号呢?显然如上图所示s1的第一组是干不过s2中括号组,但是s1的第二组可以干过s2中括号组。总结规律可以得到:将预对比的两组括号,分别去掉开头和结尾,pk剩下的两括号字符串,而pk剩下的两括号字符串即原问题本身,从而完成递归。

代码实现

最后附上本人拙劣的代码,耗时6ms,内存消耗相比动态规划小很多

#include <bits/stdc++.h>
using namespace std;

class Solution 
{
    public:
        string s1;
        string s2;
        void read()
        {
            cin>>s1;
            cin>>s2;
        }

        int getNext(const string& S, int is)
        {
            int lcnt=0;
            int rcnt=0;
            while(is<S.size())
            {
                if(S[is]=='(')
                    lcnt++;
                else
                    rcnt++;
                if(rcnt==lcnt)
                    return is;
                is++;
            }
            return is;
        }

        // 多组原子对多组原子
        bool isMatch(int l1, int r1, int l2, int r2)
        {
            int i1,i2,j1,j2;
            j1=l1-1;
            i2=l2;
            j2=getNext(s2,i2);

            while(j2<=r2)
            {
                while(1)
                {
                    i1=j1+1;;
                    if(i1>r1)
                        return false;
                    j1=getNext(s1,i1);
                    if( isCover(i1,j1,i2,j2) )
                    {
                        i2=j2+1;
                        if(i2>r2)
                            return true;
                        j2=getNext(s2,i2);
                        break;
                    }
                }
            }
            return true;
        }

        //s1的从l1到r1,能cover住s2的l2到r2吗, l1-l1是个原子,即(xxx)
        bool isCover(int l1, int r1, int l2, int r2)
        {
            if(r1-l1<r2-l2)
                return false;
            if(l2+1==r2)
                return true;
            return isMatch(l1+1,r1-1, l2+1,r2-1);

        }
        void process()
        {
            read();
            if(isMatch(0,s1.size()-1, 0, s2.size()-1))
                cout<<"Possible"<<endl;
            else
                cout<<"Impossible"<<endl;
            return ;
        }
};

int main()
{
    Solution s;
    s.process();
    return 0;
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
06-19 14:46
和女友两个人马上毕业,现在我在鹅实习995,周六日偶尔也去北京;她在北京金融007,经常忙到后半夜,周末也没啥休息机会两个人现在都不咋聊天了,一句话隔半小时甚至半天才回。&nbsp;她是个很优秀的妹子,工作也很努力,是值得学习一辈子的人。我在努力工作求转正,即便不行至少赚到了一段不错的实习经历。已经异地了半年,接下来可能还会持续是这个状态。我们都算是对方重要的人,只是感觉看上去不是很有未来的样子。希望牛友们给点的鼓励
梦旅奇缘:很难。异地首先就已经很难了,加上妹子是金融行业,忙碌高压,对情感需求很高,而且见惯纸醉金迷,你的很多优势在她那里可能就不算什么了。这种情况下,在她们那里遇到一个能及时照顾她的人,即使那人可能很多条件不如你,你也有可能被分手。 说白了,两个卷王就不太适合在一起。因为卷王最大的优势,在另一个卷王那里就不算优势了。
点赞 评论 收藏
分享
龙珠传说:nb,公务员解约不需要支付违约金吧
点赞 评论 收藏
分享
评论
7
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务