leetcode-38-Count and Say 基础题

问题

题目:[leetcode-38]

思路

1, 11, 21, 1211, 111221, …

1 is read off as “one 1” or 11.
11 is read off as “two 1s” or 21.
21 is read off as “one 2, then one 1” or 1211.

从样本来看,每一组的数字是在上一组数字的基础上获得的,所以原问题和子问题有关联,考虑递归。
下面说给定上一个字符串之后,怎么求当前字符串,就是一个统计即可。使用哈希表,key代表元素,value代表出现次数。需要注意一点,当数字不连续,需要重新统计。逻辑如下:

  1. 哈希表初始化
  2. 枚举每一个字符:
    2.1.如果哈希表为空,当前元素出现次数置1
    2.2.否则,判断:当前元素和上一个元素是否相等
    2.2.1.相等,相应元素次数加1
    2.2.2.否则,
    2.2.2.1.统计上一个元素的次数,加入结果序列。
    2.2.2.2.清空哈希表
    2.2.2.3.当前元素次数置1
  3. 统计最后一个元素的次数,加入结果序列
  4. 返回结果

代码

class Solution {
public:
    string countAndSay(int n) {
        if(!n)
            return "";
        else if(1==n)
            return "1";
        else
        {
            std::string ret = countAndSay(n-1);
            int sz = ret.size();

            std::string ans;     
            std::map<char, int> mapper;

            for( int i = 0; i < sz; ++i )
            {
                if( mapper.empty() )
                {
                    mapper[ret[i]] = 1;
                }
                else
                { 
                    if( ret[i] != ret[i-1] )
                    {
                        // 保存之前的结果
                        char cnt = '0' + mapper[ret[i-1]];
                        char val = ret[i-1] ;
                        ans.push_back( cnt );
                        ans.push_back( val );

                        // 当前元素计数
                        mapper.clear();
                        mapper[ret[i]] = 1;
                    }    
                    else
                        ++mapper[ret[i]];
                }
            }

            char cnt = '0' + mapper[ret[sz-1]];
            char val = ret[sz-1];
            ans.push_back( cnt );
            ans.push_back( val );

            return ans;
        }
    }

};

刚才女友讲了个方法,发现其实没有用hash表的必要,因为自始至终只存储了一个元素所对应的次数,改为count即可。count代表当前正在统计的元素次数。

代码1

class Solution {
public:
    string countAndSay(int n) {
        if(!n)
            return "";
        else if(1==n)
            return "1";
        else
        {
            std::string ret = countAndSay(n-1);
            std::string ans;

            int count = 0;
            int sz = ret.size();


            for( int i = 0; i < sz; ++i )
            {
                if( !i )
                {
                    count = 1;
                }
                else
                {

                    if( ret[i] != ret[i-1] )
                    {
                        // 保存之前的结果
                        char cnt = '0' + count;
                        char val = ret[i-1] ;
                        ans.push_back( cnt );
                        ans.push_back( val );

                        // 当前元素重置为1
                        count = 1;
                    }    
                    else
                        ++count;
                }
            }

            char cnt = '0' + count;
            char val = ret[sz-1];
            ans.push_back( cnt );
            ans.push_back( val );


            return ans;
        }
    }

};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值