LeetCode今日困难题收获

 

今天很不巧,碰上了困难题但是逃不掉啊,虽然大家在评论里讲简单,但是对我来说是真的难,他们可以把问题剥离出来但是我不行😭还是先学习一下他们精妙的想法吧 

方法一:动态规划

题目信息:

字符串中的每个字符都应当是小写元音字母('a', 'e', 'i', 'o', 'u')
每个元音 'a' 后面都只能跟着 'e'
每个元音 'e' 后面只能跟着 'a' 或者是 'i'
每个元音 'i' 后面 不能 再跟着另一个 'i'
每个元音 'o' 后面只能跟着 'i' 或者是 'u'
每个元音 'u' 后面只能跟着 'a'

为了使用动态规划递推,就要把后面一个字符的规则转化为前一个字符的规则

1.a前面本来可以aeiou,就是aa        ea        ia        oa        ua

aa排除,oa排除所以a前面可以是eiu

长度为i的以a为结尾的字符串数量是长度为i-1的以e以i以u为结尾的字符串的数量的和

以此类推

直接上代码

class Solution {
public:
    int countVowelPermutation(int n)
    {
        long long mod = 1e9 + 7;
        vector<long long> dp(5, 1);//定义了5元素的向量,且给出每个元素的初值为1,即dp[1]
        vector<long long> ndp(5);//ndp就是暂存
        for (int i = 2; i <= n; ++i) //从求dp[2]开始
        {
            /* a前面可以为e,u,i */
            ndp[0] = (dp[1] + dp[2] + dp[4]) % mod;
            /* e前面可以为a,i */
            ndp[1] = (dp[0] + dp[2]) % mod;
            /* i前面可以为e,o */
            ndp[2] = (dp[1] + dp[3]) % mod;
            /* o前面可以为i */
            ndp[3] = dp[2];
            /* u前面可以为i,o */
            ndp[4] = (dp[2] + dp[3]) % mod;
            dp = ndp;//还可以这样直接
        }
        return accumulate(dp.begin(), dp.end(), 0ll) % mod;
    }
};

获得: 

1.vector的使用真的十分简洁方便,还可以直接传递复制,这个真的需要好好学一下

2.规范性:因为一直用的是long long 型数据,所以这样的话最后使用accumulate函数最好用0ll而不是0,防止有不合适的值出现

3.accumulate函数的用法有个博主的代码很好

#include <vector>
#include <numeric>
#include <functional>
#include <iostream>

using namespace std;

int main( ) 
{

   vector <int> v1, v2( 20 );
   vector <int>::iterator Iter1, Iter2;

   int i;
   for ( i = 1 ; i < 21 ; i++ )
   {
      v1.push_back( i );
   }

   cout << "最初向量v1中个元素的值为:\n ( " ;
   for ( Iter1 = v1.begin( ) ; Iter1 != v1.end( ) ; Iter1++ )
      cout << *Iter1 << " ";
   cout << ")." << endl;

   // accumulate函数的第一个功能,求和
   int total;
   total = accumulate ( v1.begin ( ) , v1.end ( ) , 0 );

   cout << "整数从1到20的和为: " 
        << total << "." << endl;

   // 构造一个前n项和的向量
   int j = 0, partotal;
   for ( Iter1 = v1.begin( ) + 1; Iter1 != v1.end( ) + 1 ; Iter1++ )
   {
      partotal = accumulate ( v1.begin ( ) , Iter1 , 0 );
      v2 [ j ] = partotal;
      j++;
   }

   cout << "前n项和分别为:\n ( " ;
   for ( Iter2 = v2.begin( ) ; Iter2 != v2.end( ) ; Iter2++ )
      cout << *Iter2 << " ";
   cout << ")." << endl << endl;

   // accumulate函数的第二个功能,计算连乘积
   vector <int> v3, v4( 10 );
   vector <int>::iterator Iter3, Iter4;

   int s;
   for ( s = 1 ; s < 11 ; s++ )
   {
      v3.push_back( s );
   }

   cout << "向量v3的初始值分别为:\n ( " ;
   for ( Iter3 = v3.begin( ) ; Iter3 != v3.end( ) ; Iter3++ )
      cout << *Iter3 << " ";
   cout << ")." << endl;

   int ptotal;
   ptotal = accumulate ( v3.begin ( ) , v3.end ( ) , 1 , multiplies<int>( ) );

   cout << "整数1到10的连乘积为: " 
        << ptotal << "." << endl;

   // 构造一个前n项积的向量
   int k = 0, ppartotal;
   for ( Iter3 = v3.begin( ) + 1; Iter3 != v3.end( ) + 1 ; Iter3++ ) {
      ppartotal = accumulate ( v3.begin ( ) , Iter3 , 1 , multiplies<int>( ) );
      v4 [ k ] = ppartotal;
      k++;
   }

   cout << "前n项积分别为:\n ( " ;
   for ( Iter4 = v4.begin( ) ; Iter4 != v4.end( ) ; Iter4++ )
      cout << *Iter4 << " ";
   cout << ")." << endl;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值