LeetCode 726. Number of Atoms

题意:给出一个化合物的化学式 eg, Mg(OH)2 and K4(ON(SO3)2)2,统计出其每个原子的个数

很明显用递归做,如果遇到a(bcd)ef,则bcd构成一个子问题,递归处理统计出各个原子出现的频率(用map记录),如果e是个数字,返回后merge频率乘上该数字即可。

但是需要保证先处理外面的括号,再处理内部的括号e.g., (a(bdc)e)。我把一块当做merge inteval处理了,但感觉没必要,因为不会出现([)]的情况。用栈可以得出所有括号匹配的区间,merge interval之后得到的区间都是最外层的。e.g., (ab)c(de), a(bc[内部的括号在子问题中再处理]d)e。

另外统计括号外部的原子频率时,需要跳过括号内部的部分。可以Maintain一个cnt,遇到区间左端点+1,遇到区间右端点-1,cnt=0则表示区间之外。

wa了几次都是merge interval最初或者最后忘记记录interval了。另外数字可能不是一位数。

复杂度是N^2,因为每个字母只会访问一次,处理(abc)之后如果原先的(abc)d中d是数字,则需要O(N)去计算merge之后的频率。

#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<string>
#include<cmath>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
#include<stack>
using namespace std;

//leetcode 726. Number of Atoms
const int maxn=1010;
int T;
int N;
int M;
class Solution {
public:
    //save the branket position left is i, right is pos[i]
    string countOfAtoms(string formula) {
        cout<<formula<<endl;
        map<string,int>mp=dfs(0,formula.length(),formula);
        string ret;
        for(auto iter=mp.begin();iter!=mp.end();iter++)
        {
            ret+=iter->first;
            if(iter->second!=1)
            {
                int tmp=iter->second;
                string s="";
                while(tmp!=0)
                {
                    s+=(tmp%10)+'0';
                    tmp/=10;
                }
                reverse(s.begin(),s.end());
                ret+=s;

            }
            cout<<iter->first<<" "<<iter->second<<endl;
        }
        return ret;
    }
    map<string,int> dfs(int st,int ed,string formula)
    {
//        cout<<st<<" start dfs "<<ed<<endl;
        int pos[maxn];
        memset(pos,0,sizeof(pos));
        map<string,int>mp;
        stack<int>sta;
        vector<pair<int,int> >interval;
        vector<pair<int,int> >merged_interval;
        for(int i=st;i<ed;i++)
        {
            if(formula[i]=='(')
            {
                sta.push(i);
            }
            if(formula[i]==')')
            {
                int tmp=sta.top();

                sta.pop();
                interval.push_back(make_pair(tmp,i));
            }
        }

        if(interval.size()!=0)
        {
            sort(interval.begin(),interval.end());
            int interval_st=interval[0].first;
            int interval_ed=interval[0].second;
            pos[interval_st]=1;
            pos[interval_ed]=-1;
            for(int i=0;i<interval.size();i++)
            {
//                cout<<"interval "<<interval[i].first<<" "<<interval[i].second<<endl;
                if(interval_ed<interval[i].second)
                {
                    merged_interval.push_back(make_pair(interval_st,interval_ed));
                    interval_st=interval[i].first;
                    interval_ed=interval[i].second;
                    pos[interval_st]=1;
                    pos[interval_ed]=-1;
                }
                else
                {
                    interval_ed=max(interval_ed,interval[i].second);
                }
            }
            merged_interval.push_back(make_pair(interval_st,interval_ed));
            pos[interval_st]=1;
            pos[interval_ed]=-1;
        }
//        cout<<merged_interval.size()<<endl;
        for(int i=0;i<merged_interval.size();i++)
        {
//            cout<<"merged interval "<<merged_interval[i].first<<" "<<merged_interval[i].second<<endl;
            map<string,int>mp2=dfs(merged_interval[i].first+1,merged_interval[i].second,formula);
            int prod=1;
            int idx=merged_interval[i].second+1;
//            cout<<formula<<endl;
            if(idx<formula.length()&&formula[idx]>='0'&&formula[idx]<='9')
            {
                int num=0;
                while(idx<formula.length()&&formula[idx]>='0'&&formula[idx]<='9')
                {
//                    cout<<idx<<" "<<formula[idx]<<endl;
                    num*=10;
                    num+=formula[idx]-'0';
                    idx++;
                }
//                cout<<num<<endl;
                prod=num;
            }
            for(auto iter=mp2.begin();iter!=mp2.end();iter++)
            {
//                cout<<"Add "<<iter->first<<" "<<iter->second<<" "<<prod<<" "<<iter->second*prod<<endl;
                if(mp.find(iter->first)==mp.end())
                {
                    mp[iter->first]=iter->second*prod;
                }
                else
                {
                    mp[iter->first]+=iter->second*prod;
                }
//                cout<<"after add in mp "<<mp[iter->first]<<endl;
            }
        }
        int cnt=0;
        cout<<st<<" "<<ed<<endl;
        for(int i=st;i<ed;i++)
        {
            cnt+=pos[i];
//            cout<<i<<" add at end "<<formula[i]<<" "<<pos[i]<<" "<<cnt<<endl;

            if(cnt==0&&formula[i]>='A'&&formula[i]<='Z')
            {
                string tmp=" ";
                tmp[0]=formula[i];
                i++;
                while(i<formula.length()&&formula[i]>='a'&&formula[i]<='z')
                {
                    tmp+=formula[i];
                    i++;
                }

                if(i<formula.length()&&formula[i]>='0'&&formula[i]<='9')
                {
                    int num=0;
                    while(i<formula.length()&&formula[i]>='0'&&formula[i]<='9')
                    {
                        num*=10;
                        num+=formula[i]-'0';
                        i++;
                    }
                    mp[tmp]+=num;
//                    cout<<tmp<<" add "<<num<<endl;
                }

                else
                {
                    mp[tmp]+=1;
//                    cout<<tmp<<" add 1 "<<endl;

                }
                i--;

            }
        }
//        cout<<"return "<<endl;
        return mp;
    }
};
int main()
{
    freopen("input.txt","r",stdin);
    cin>>T;
    for(int ca=1;ca<=T;ca++)
    {
        string S;
        cin>>S;
        cin.ignore();
        Solution sol;
        cout<<"Case #"<<ca<<": "<<sol.countOfAtoms(S)<<endl;
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值