问题
思路
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代表出现次数。需要注意一点,当数字不连续,需要重新统计。逻辑如下:
- 哈希表初始化
- 枚举每一个字符:
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 - 统计最后一个元素的次数,加入结果序列
- 返回结果
代码
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;
}
}
};