• 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/

     
    雪儿言
  • 相关阅读:
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    449. Serialize and Deserialize BST
    114. Flatten Binary Tree to Linked List
    199. Binary Tree Right Side View
    173. Binary Search Tree Iterator
    98. Validate Binary Search Tree
    965. Univalued Binary Tree
    589. N-ary Tree Preorder Traversal
    eclipse设置总结
  • 原文地址:https://www.cnblogs.com/weixq351/p/15007270.html
Copyright © 2020-2023  润新知