zoukankan      html  css  js  c++  java
  • 20210718力扣第249场周赛(五)

    力扣第249场周赛

    1930. 长度为 3 的不同回文子序列

    题目:

    给你一个字符串 s ,返回 s 中 长度为 3 的不同回文子序列 的个数。

    即便存在多种方法来构建相同的子序列,但相同的子序列只计数一次。

    回文 是正着读和反着读一样的字符串。

    子序列 是由原字符串删除其中部分字符(也可以不删除)且不改变剩余字符之间相对顺序形成的一个新字符串。

    例如,"ace" 是 "abcde" 的一个子序列。

    提示:

    • 3 <= s.length <= 105
    • s 仅由小写英文字母组成

    题解:

    主要找到26个字母的最开始位置和最终的位置;

    然后找到相同字母之间最多的不同字母数量;

    然后把不同的数量统计在ans中即可。

    需要会map的map.count和string s的s.size()和统计出现的不同的字母,相当于标注,用vector[i]==2(一个常量)。

    map1.count(i)==0 表示字母i没有出现在map1中;map1.count(i)==1 表示字母i出现在map1中。

    代码:

     1 class Solution {
     2 public:
     3     int countPalindromicSubsequence(string s) {
     4         map<char,int> map1;
     5         map<char,int> map2;
     6         int n=s.size();
     7 
     8         for(int i=0;i<n;i++)
     9         {
    10             if(map1.count(s[i])==1)//不断更新字母出现在终点的位置
    11             {
    12                 map2[s[i]]=i;
    13             }
    14             else
    15             {
    16                 map1[s[i]]=i;
    17             }
    18         }
    19         int ans=0;
    20         for(char i='a';i<'a'+26;i++)
    21         {
    22             if(!map1.count(i) || !map2.count(i))
    23             {
    24                 continue;
    25             }
    26             int start=map1[i];
    27             int end=map2[i];
    28             vector<int> vec(26);//用vec可变数组保存相距最远的相同字母之间的不同的字母的个数,最多是26个,
    29             //也就是vec最长是26的长度
    30             for(int j=start+1;j<end;j++)
    31             {
    32                 //把所有存在的可能性统计出来
    33                 vec[s[j]-'a']=2;
    34             }
    35             for(int k=0;k<26;k++)
    36             {
    37                 if(vec[k]==2)
    38                 ans++;
    39             }
    40 
    41         }
    42         return ans;
    43     }
    44 };

    1931. 用三种不同颜色为网格涂色

     题目:

    给你两个整数 m 和 n 。构造一个 m x n 的网格,其中每个单元格最开始是白色。请你用 红、绿、蓝 三种颜色为每个单元格涂色。所有单元格都需要被涂色。

    涂色方案需要满足:不存在相邻两个单元格颜色相同的情况 。返回网格涂色的方法数。因为答案可能非常大, 返回 对 109 + 7 取余 的结果。

    示例 3:

    输入:m = 5, n = 5
    输出:580986


    提示:

    • 1 <= m <= 5
    • 1 <= n <= 1000

    题解:

    此题目的m很小,只有5,所以可以从这里考虑。状态压缩dp问题。

    方法一,也有代码如下,主要是分别求解出m分别等于1,2,3,4,5,的时候的状态数量。

    方法二,运用动态规划,求解此题。dp[n+1][s],n+1表示列,s表示m行且一列时候的状态数量。

    代码:

     1 class Solution {
     2 public:
     3     int colorTheGrid(int m, int n) {
     4         long long mod = 1000000007;
     5         if(m==1)
     6         {
     7             int ans=3;
     8             for(int i=1;i<n;++i)    ans= ans * 2LL % mod;
     9             return ans;
    10         }
    11         else if(m==2)
    12         {
    13             int fi = 6;
    14             for(int i=1;i<n;++i)    fi= 3LL * fi % mod;
    15             return fi;
    16         }
    17         else if(m==3)
    18         {
    19             int fi0 = 6, fi1 = 6;
    20             for (int i = 1; i < n; ++i) {
    21                 int new_fi0 = (2LL * fi0 + 2LL * fi1) % mod;
    22                 int new_fi1 = (2LL * fi0 + 3LL * fi1) % mod;
    23                 fi0 = new_fi0;
    24                 fi1 = new_fi1;
    25             }
    26             return ((long long)fi0 + fi1) % mod;
    27         }
    28         else if(m==4)
    29         {
    30             //ABAB//ABAC//ABCA//ABCB
    31             int fi0 = 6, fi1 = 6, fi2=6, fi3=6;
    32             for (int i = 1; i < n; ++i) {
    33                 int new_fi0 = (3LL * fi0 + 2LL * fi1+ 1LL*fi2+ 2LL*fi3) % mod;
    34                 int new_fi1 = (2LL * fi0 + 2LL * fi1+ 1LL*fi2+2LL*fi3) % mod;
    35                 int new_fi2 = (1LL * fi0 + 1LL * fi1+ 2LL*fi2 +1LL*fi3) % mod;
    36                 int new_fi3 = (2LL * fi0 + 2LL * fi1+ 1LL*fi2+2LL*fi3) % mod;
    37                 fi0 = new_fi0;
    38                 fi1 = new_fi1;
    39                 fi2 = new_fi2;
    40                 fi3 = new_fi3;
    41             }
    42             return ((long long)fi0 + fi1+ fi2+ fi3) % mod;
    43         }
    44         else
    45         {
    46             //ABABA//ABABC//ABACA//ABACB//ABCAB//ABCAC//ABCBA//ABCBC
    47             int fi0 = 6, fi1 = 6, fi2=6 ,fi3 =6, fi4=6, fi5=6, fi6=6, fi7=6;
    48             for (int i = 1; i < n; ++i) {
    49                 int new_fi0 = (3LL * fi0 + 2LL * fi1+ 2LL*fi2+ 1LL*fi3+ 0LL*fi4 +1LL*fi5 +2LL*fi6+2LL*fi7) % mod;
    50                 int new_fi1 = (2LL * fi0 + 2LL * fi1+ 2LL*fi2+ 1LL*fi3+ 1LL*fi4 +1LL*fi5 +1LL*fi6+1LL*fi7) % mod;
    51                 int new_fi2 = (2LL * fi0 + 2LL * fi1+ 2LL*fi2+ 1LL*fi3+ 0LL*fi4 +1LL*fi5 +2LL*fi6+2LL*fi7) % mod;
    52                 int new_fi3 = (1LL * fi0 + 1LL * fi1+ 1LL*fi2+ 2LL*fi3+ 1LL*fi4 +1LL*fi5 +1LL*fi6+1LL*fi7) % mod;
    53                 int new_fi4 = (0LL * fi0 + 1LL * fi1+ 0LL*fi2+ 1LL*fi3+ 2LL*fi4 +1LL*fi5 +0LL*fi6+1LL*fi7) % mod;
    54                 int new_fi5 = (1LL * fi0 + 1LL * fi1+ 1LL*fi2+ 1LL*fi3+ 1LL*fi4 +2LL*fi5 +1LL*fi6+1LL*fi7) % mod;
    55                 int new_fi6 = (2LL * fi0 + 1LL * fi1+ 2LL*fi2+ 1LL*fi3+ 0LL*fi4 +1LL*fi5 +2LL*fi6+1LL*fi7) % mod;
    56                 int new_fi7 = (2LL * fi0 + 1LL * fi1+ 2LL*fi2+ 1LL*fi3+ 1LL*fi4 +1LL*fi5 +1LL*fi6+2LL*fi7) % mod;
    57                 fi0 = new_fi0;
    58                 fi1 = new_fi1;
    59                 fi2 = new_fi2;
    60                 fi3 = new_fi3;
    61                 fi4 = new_fi4;
    62                 fi5 = new_fi5;
    63                 fi6 = new_fi6;
    64                 fi7 = new_fi7;
    65             }
    66             return ((long long)fi0 + fi1+ fi2+ fi3+ fi4 + fi5+ fi6+ fi7) % mod;
    67         }
    68     }
    69 };

     代码二:

     1 class Solution {
     2 public:
     3     vector<vector<int>> v;
     4     
     5     typedef long long LL;
     6     int mod = 1e9 + 7;
     7     
     8     int valid(int m)//这是m行的状态数量
     9     {
    10         if (m == 5)
    11             for (int i = 0; i < 3; i ++)
    12             for (int j = 0; j < 3; j ++)
    13             for (int k = 0; k < 3; k ++)
    14             for (int h = 0; h < 3; h ++)
    15             for (int l = 0; l < 3; l ++)
    16             if (i != j && j != k && k != h && h != l)
    17                 v.push_back({i, j, k, h, l});
    18         
    19         if (m == 4)
    20             for (int i = 0; i < 3; i ++)
    21             for (int j = 0; j < 3; j ++)
    22             for (int k = 0; k < 3; k ++)
    23             for (int h = 0; h < 3; h ++)
    24             if (i != j && j != k && k != h)
    25                 v.push_back({i, j, k, h});
    26         
    27         if (m == 3)
    28             for (int i = 0; i < 3; i ++)
    29             for (int j = 0; j < 3; j ++)
    30             for (int k = 0; k < 3; k ++)
    31             if (i != j && j != k)
    32                 v.push_back({i, j, k});
    33         
    34         if (m == 2)
    35             for (int i = 0; i < 3; i ++)
    36             for (int j = 0; j < 3; j ++)
    37             if (i != j)
    38                 v.push_back({i, j});
    39         
    40         if (m == 1)
    41             for (int i = 0; i < 3; i ++)
    42                 v.push_back({i});
    43 
    44         return v.size();
    45     }
    46     
    47     bool is_valid(int st1, int st2, int m)//判断状态是否正确
    48     {
    49         for (int i = 0; i < m; i ++)
    50             if (v[st1][i] == v[st2][i]) return false;
    51         return true;
    52     }
    53 
    54     int colorTheGrid(int m, int n) {
    55         int s = valid(m);
    56         LL dp[n+1][s];//注意是n+1,n会报错
    57         memset(dp, 0, sizeof dp);//状态压缩DP[n+1][s]初始化为0
    58         for (int i = 0; i < s; i ++)
    59         {
    60             dp[1][i] = 1;
    61         }
    62         if (n == 1) return s;
    63         for (int i = 2; i <= n; i ++)
    64         {
    65             for (int sti = 0; sti < s; sti ++)
    66             {
    67                 for (int stj = 0; stj < s; stj ++)
    68                 {
    69                     if (is_valid(sti, stj, m))
    70                         dp[i][sti] = (dp[i][sti] + dp[i - 1][stj]) % mod;//当前列是基于前一列正确的状态,并且需要 % mod
    71                 }
    72             }
    73         }
    74 
    75         LL ans = 0;
    76         for (int i = 0; i < s; i ++)
    77         {
    78            ans = (ans + dp[n][i]) % mod;
    79         }
    80         return (int)ans;
    81     }
    82 };

    参考链接:https://leetcode-cn.com/problems/unique-length-3-palindromic-subsequences/

    https://leetcode-cn.com/problems/unique-length-3-palindromic-subsequences/solution/c-xun-zhao-hui-wen-guan-jian-huan-shi-yi-264r/

     https://leetcode-cn.com/problems/painting-a-grid-with-three-different-colors/

    https://leetcode-cn.com/problems/painting-a-grid-with-three-different-colors/solution/onda-cong-ming-suan-fa-tui-liao-ge-xiao-nvfk0/

    https://leetcode-cn.com/problems/painting-a-grid-with-three-different-colors/solution/fei-chang-zhi-guan-de-dong-tai-gui-hua-b-f34f/

     
    雪儿言
  • 相关阅读:
    Nginx的configure各项中文说明
    nginx+keepalived高可用及双主模式
    nginx实现请求的负载均衡 + keepalived实现nginx的高可用
    Keepalived详细介绍简介
    keepalived vip漂移基本原理及选举算法
    keepalived脑裂问题查找
    计算机网络的三种通讯模式(单播,广播,组播)
    二层交换机、三层交换机、路由器
    Linux /var/log下的各种日志文件详解
    报文、帧、数据包等的区别
  • 原文地址:https://www.cnblogs.com/weixq351/p/15007270.html
Copyright © 2011-2022 走看看