思路:dp。
这道题其实也是爬楼梯的变形。
不过,这里需要分类讨论一下:就是选择7或者9的时候是4种递推情况,其他的都是3种。
而且,我们可以利用dp数组过程记录的特点运用在本题当中。
这里需要解决几个问题:
1.递推方程怎么定义,dp怎么定义?
2.对于不同的字符,我们怎么处理?
3.我们针对不同的字符,应该怎么计数才好?
问题1我们在开头已经解决了。
问题2,我们是需要分开处理的,就像上面说的那样,我们需要对不同的字符以不同的状态dp。
问题3,这里是作者需要学习的地方,因为这里作者在思考的时候并不知道怎么写,只会一个劲儿地堆if else语句,堆了最后发现自己不会写了,这是编程能力上有点欠缺了。
只需要连续判断相邻两个字符是不是相同就行了,因为我们是分类讨论数字字符,所以相同的字符称为一堆,我们一堆一堆的计数,就像用刀分开来几段。按照乘法原理进行相乘就可以了(数学不好的可以补一下这个原理)。
注意:数据范围上可能会暴int,所以在递推数的时候和计数的时候都应该开到long,然后在取模之后再转化为int,这个是相当细节的点。
上代码:
class Solution {
public:int countTexts(string pressedKeys) {int dp1[100010];int dp2[100010];dp1[0]=dp1[1]=1;dp2[0]=dp2[1]=1;dp1[2]=dp2[2]=2;dp1[3]=dp2[3]=4;for(int i=4;i<100010;i++){dp1[i]=(int)(((long)dp1[i-1]+dp1[i-2]+dp1[i-3])%1000000007);dp2[i]=(int)(((long)dp2[i-1]+dp2[i-2]+dp2[i-3]+dp2[i-4])%1000000007);}int ans=1;int counts=0;for(int i=0;i<pressedKeys.size();i++){++counts;char c=pressedKeys[i];if(i==pressedKeys.size()-1||c!=pressedKeys[i+1]){ans=(c=='7'||c=='9')?(int)(((long)ans*dp2[counts])%1000000007):(int)(((long)ans*dp1[counts])%1000000007);counts=0;}}return ans;}
};