Leetcode 每日一题和每日一题的下一题刷题笔记 21/30

117 阅读11分钟

Leetcode 每日一题和每日一题的下一题刷题笔记 21/30

写在前面

这是我参与更文挑战的第21天,活动详情查看:更文挑战

快要毕业了,才发现自己被面试里的算法题吊起来锤。没办法只能以零基础的身份和同窗们共同加入了力扣刷题大军。我的同学们都非常厉害,他们平时只是谦虚,口头上说着自己不会,而我是真的不会。。。乘掘金鼓励新人每天写博客,我也凑个热闹,记录一下每天刷的前两道题,这两道题我精做。我打算每天刷五道题,其他的题目嘛,也只能强行背套路了,就不发在博客里了。

本人真的只是一个菜鸡,解题思路什么的就不要从我这里参考了,编码习惯也需要改进,各位如果想找刷题高手请教问题我觉得去找 宫水三叶的刷题日记 这位大佬比较好。我在把题目做出来之前尽量不去看题解,以免和大佬的内容撞车。

另外我也希望有得闲的大佬提供一些更高明的解题思路给我,欢迎讨论哈!

好了废话不多说开始第二十一天的前两道题吧!

2021.6.21 每日一题

401. 二进制手表

没人比我更懂暴力方法[手动滑稽]


class Solution {
public:
    vector<string> readBinaryWatch(int turnedOn) {
        vector<vector<string>> all = {
            { "0:00"}, 
            { "0:01",  "0:02",  "0:04",  "0:08",  "0:16",  "0:32",  "1:00",  "2:00",  "4:00",  "8:00"}, 
            { "0:03",  "0:05",  "0:06",  "0:09",  "0:10",  "0:12",  "0:17",  "0:18",  "0:20",  "0:24",  "0:33",  "0:34",  
              "0:36",  "0:40",  "0:48",  "1:01",  "1:02",  "1:04",  "1:08",  "1:16",  "1:32",  "2:01",  "2:02",  "2:04",  
              "2:08",  "2:16",  "2:32",  "3:00",  "4:01",  "4:02",  "4:04",  "4:08",  "4:16",  "4:32",  "5:00",  "6:00",  
              "8:01",  "8:02",  "8:04",  "8:08",  "8:16",  "8:32",  "9:00", "10:00"}, 
            { "0:07",  "0:11",  "0:13",  "0:14",  "0:19",  "0:21",  "0:22",  "0:25",  "0:26",  "0:28",  "0:35",  "0:37",  
              "0:38",  "0:41",  "0:42",  "0:44",  "0:49",  "0:50",  "0:52",  "0:56",  "1:03",  "1:05",  "1:06",  "1:09",  
              "1:10",  "1:12",  "1:17",  "1:18",  "1:20",  "1:24",  "1:33",  "1:34",  "1:36",  "1:40",  "1:48",  "2:03",  
              "2:05",  "2:06",  "2:09",  "2:10",  "2:12",  "2:17",  "2:18",  "2:20",  "2:24",  "2:33",  "2:34",  "2:36",  
              "2:40",  "2:48",  "3:01",  "3:02",  "3:04",  "3:08",  "3:16",  "3:32",  "4:03",  "4:05",  "4:06",  "4:09",  
              "4:10",  "4:12",  "4:17",  "4:18",  "4:20",  "4:24",  "4:33",  "4:34",  "4:36",  "4:40",  "4:48",  "5:01",  
              "5:02",  "5:04",  "5:08",  "5:16",  "5:32",  "6:01",  "6:02",  "6:04",  "6:08",  "6:16",  "6:32",  "7:00",  
              "8:03",  "8:05",  "8:06",  "8:09",  "8:10",  "8:12",  "8:17",  "8:18",  "8:20",  "8:24",  "8:33",  "8:34",  
              "8:36",  "8:40",  "8:48",  "9:01",  "9:02",  "9:04",  "9:08",  "9:16",  "9:32", "10:01", "10:02", "10:04", 
             "10:08", "10:16", "10:32", "11:00"}, 
            { "0:15",  "0:23",  "0:27",  "0:29",  "0:30",  "0:39",  "0:43",  "0:45",  "0:46",  "0:51",  "0:53",  "0:54",  
              "0:57",  "0:58",  "1:07",  "1:11",  "1:13",  "1:14",  "1:19",  "1:21",  "1:22",  "1:25",  "1:26",  "1:28",  
              "1:35",  "1:37",  "1:38",  "1:41",  "1:42",  "1:44",  "1:49",  "1:50",  "1:52",  "1:56",  "2:07",  "2:11",  
              "2:13",  "2:14",  "2:19",  "2:21",  "2:22",  "2:25",  "2:26",  "2:28",  "2:35",  "2:37",  "2:38",  "2:41",  
              "2:42",  "2:44",  "2:49",  "2:50",  "2:52",  "2:56",  "3:03",  "3:05",  "3:06",  "3:09",  "3:10",  "3:12",  
              "3:17",  "3:18",  "3:20",  "3:24",  "3:33",  "3:34",  "3:36",  "3:40",  "3:48",  "4:07",  "4:11",  "4:13",  
              "4:14",  "4:19",  "4:21",  "4:22",  "4:25",  "4:26",  "4:28",  "4:35",  "4:37",  "4:38",  "4:41",  "4:42",  
              "4:44",  "4:49",  "4:50",  "4:52",  "4:56",  "5:03",  "5:05",  "5:06",  "5:09",  "5:10",  "5:12",  "5:17",  
              "5:18",  "5:20",  "5:24",  "5:33",  "5:34",  "5:36",  "5:40",  "5:48",  "6:03",  "6:05",  "6:06",  "6:09",  
              "6:10",  "6:12",  "6:17",  "6:18",  "6:20",  "6:24",  "6:33",  "6:34",  "6:36",  "6:40",  "6:48",  "7:01",  
              "7:02",  "7:04",  "7:08",  "7:16",  "7:32",  "8:07",  "8:11",  "8:13",  "8:14",  "8:19",  "8:21",  "8:22",  
              "8:25",  "8:26",  "8:28",  "8:35",  "8:37",  "8:38",  "8:41",  "8:42",  "8:44",  "8:49",  "8:50",  "8:52",  
              "8:56",  "9:03",  "9:05",  "9:06",  "9:09",  "9:10",  "9:12",  "9:17",  "9:18",  "9:20",  "9:24",  "9:33",  
              "9:34",  "9:36",  "9:40",  "9:48", "10:03", "10:05", "10:06", "10:09", "10:10", "10:12", "10:17", "10:18", 
             "10:20", "10:24", "10:33", "10:34", "10:36", "10:40", "10:48", "11:01", "11:02", "11:04", "11:08", "11:16", 
             "11:32"}, 
            { "0:31",  "0:47",  "0:55",  "0:59",  "1:15",  "1:23",  "1:27",  "1:29",  "1:30",  "1:39",  "1:43",  "1:45",  
              "1:46",  "1:51",  "1:53",  "1:54",  "1:57",  "1:58",  "2:15",  "2:23",  "2:27",  "2:29",  "2:30",  "2:39",  
              "2:43",  "2:45",  "2:46",  "2:51",  "2:53",  "2:54",  "2:57",  "2:58",  "3:07",  "3:11",  "3:13",  "3:14",  
              "3:19",  "3:21",  "3:22",  "3:25",  "3:26",  "3:28",  "3:35",  "3:37",  "3:38",  "3:41",  "3:42",  "3:44",  
              "3:49",  "3:50",  "3:52",  "3:56",  "4:15",  "4:23",  "4:27",  "4:29",  "4:30",  "4:39",  "4:43",  "4:45",  
              "4:46",  "4:51",  "4:53",  "4:54",  "4:57",  "4:58",  "5:07",  "5:11",  "5:13",  "5:14",  "5:19",  "5:21",  
              "5:22",  "5:25",  "5:26",  "5:28",  "5:35",  "5:37",  "5:38",  "5:41",  "5:42",  "5:44",  "5:49",  "5:50",  
              "5:52",  "5:56",  "6:07",  "6:11",  "6:13",  "6:14",  "6:19",  "6:21",  "6:22",  "6:25",  "6:26",  "6:28",  
              "6:35",  "6:37",  "6:38",  "6:41",  "6:42",  "6:44",  "6:49",  "6:50",  "6:52",  "6:56",  "7:03",  "7:05",  
              "7:06",  "7:09",  "7:10",  "7:12",  "7:17",  "7:18",  "7:20",  "7:24",  "7:33",  "7:34",  "7:36",  "7:40",  
              "7:48",  "8:15",  "8:23",  "8:27",  "8:29",  "8:30",  "8:39",  "8:43",  "8:45",  "8:46",  "8:51",  "8:53",  
              "8:54",  "8:57",  "8:58",  "9:07",  "9:11",  "9:13",  "9:14",  "9:19",  "9:21",  "9:22",  "9:25",  "9:26",  
              "9:28",  "9:35",  "9:37",  "9:38",  "9:41",  "9:42",  "9:44",  "9:49",  "9:50",  "9:52",  "9:56", "10:07", 
             "10:11", "10:13", "10:14", "10:19", "10:21", "10:22", "10:25", "10:26", "10:28", "10:35", "10:37", "10:38", 
             "10:41", "10:42", "10:44", "10:49", "10:50", "10:52", "10:56", "11:03", "11:05", "11:06", "11:09", "11:10", 
             "11:12", "11:17", "11:18", "11:20", "11:24", "11:33", "11:34", "11:36", "11:40", "11:48"}, 
            { "1:31",  "1:47",  "1:55",  "1:59",  "2:31",  "2:47",  "2:55",  "2:59",  "3:15",  "3:23",  "3:27",  "3:29",  
              "3:30",  "3:39",  "3:43",  "3:45",  "3:46",  "3:51",  "3:53",  "3:54",  "3:57",  "3:58",  "4:31",  "4:47",  
              "4:55",  "4:59",  "5:15",  "5:23",  "5:27",  "5:29",  "5:30",  "5:39",  "5:43",  "5:45",  "5:46",  "5:51",  
              "5:53",  "5:54",  "5:57",  "5:58",  "6:15",  "6:23",  "6:27",  "6:29",  "6:30",  "6:39",  "6:43",  "6:45",  
              "6:46",  "6:51",  "6:53",  "6:54",  "6:57",  "6:58",  "7:07",  "7:11",  "7:13",  "7:14",  "7:19",  "7:21",  
              "7:22",  "7:25",  "7:26",  "7:28",  "7:35",  "7:37",  "7:38",  "7:41",  "7:42",  "7:44",  "7:49",  "7:50",  
              "7:52",  "7:56",  "8:31",  "8:47",  "8:55",  "8:59",  "9:15",  "9:23",  "9:27",  "9:29",  "9:30",  "9:39",  
              "9:43",  "9:45",  "9:46",  "9:51",  "9:53",  "9:54",  "9:57",  "9:58", "10:15", "10:23", "10:27", "10:29", 
             "10:30", "10:39", "10:43", "10:45", "10:46", "10:51", "10:53", "10:54", "10:57", "10:58", "11:07", "11:11", 
             "11:13", "11:14", "11:19", "11:21", "11:22", "11:25", "11:26", "11:28", "11:35", "11:37", "11:38", "11:41", 
             "11:42", "11:44", "11:49", "11:50", "11:52", "11:56"}, 
            { "3:31",  "3:47",  "3:55",  "3:59",  "5:31",  "5:47",  "5:55",  "5:59",  "6:31",  "6:47",  "6:55",  "6:59",  
              "7:15",  "7:23",  "7:27",  "7:29",  "7:30",  "7:39",  "7:43",  "7:45",  "7:46",  "7:51",  "7:53",  "7:54",  
              "7:57",  "7:58",  "9:31",  "9:47",  "9:55",  "9:59", "10:31", "10:47", "10:55", "10:59", "11:15", "11:23", 
             "11:27", "11:29", "11:30", "11:39", "11:43", "11:45", "11:46", "11:51", "11:53", "11:54", "11:57", "11:58"}, 
            { "7:31",  "7:47",  "7:55",  "7:59", "11:31", "11:47", "11:55", "11:59"}, 
            {}, 
            {}
        };
        return all[turnedOn];
    }
};

image.png

image.png

2021.6.21 每日一题下面的题

1639. 通过给定词典构造目标字符串的方案数

由于 words 中所有单词的长度均等于 N,因此能够维护一个计数数组 cnt,其中 cnt[i][ch] 表示在所有单词的第 i 个字符中,字符 ch 出现的次数。

words_after[i] 为将 words 的每个单词从第 i 个字符起截取,得到的剩余部分字典(想象一下一本单词书的内容是分多列的,第一列是单词,紧跟着的第二列是汉译,如此两列为一对在书页上排列开来。我用一把宽尺子遮住一页上某一列的单词和汉译,这两列后面剩下的单词和汉译就是这一页的剩余部分,像下面这样)。

Day 1 word list

|---English---|---Chinese---|---English---|---Chinese---|---English---|---Chinese---|---English---|---Chinese---|

|abandon------|pao-qi-------|accumulate---|ji-lei-------|accumulate---|ji-lei-------|accumulate---|ji-lei-------|

|abandon------|pao-qi-------|accumulate---|ji-lei-------|accumulate---|ji-lei-------|accumulate---|ji-lei-------|

|abandon------|pao-qi-------|accumulate---|ji-lei-------|accumulate---|ji-lei-------|accumulate---|ji-lei-------|

|abandon------|pao-qi-------|accumulate---|ji-lei-------|accumulate---|ji-lei-------|accumulate---|ji-lei-------|

|abandon------|pao-qi-------|accumulate---|ji-lei-------|accumulate---|ji-lei-------|accumulate---|ji-lei-------|

随后记 dp[i][j] 为:以 words_after[i] 为字典,构造字符串 target_after[j] 的方案数。

现在,考虑如何构造字符串 target_after[j] 的首个字符,有以下两种情况:

不使用字典中位置为 i 的字符。此时,问题归结于使用 words_after[i+1] 为字典构造字符串的情形,故相应的方案数为 dp[i+1][j]

使用字典中位置为 i 的字符。此时,整个字典中,共有 cnt[i][target[j]] 个单词可供选择。在选择其中任意一个单词之后,根据题意,我们不能再选择任何一个单词的第 i 个字符或其之前的字符。因此,此后为了得到后面的字符串 target_after[j+1],会有 dp[i+1][j+1] 种方案。 这样,总的方案数目为:

dp[i][j] = dp[i+1][j] + dp[i+1][j+1] * cnt[i][target[j]]


class Solution {
public:
    const int mod = 1e9+7;
    long dfs(vector<vector<long>>& dp, vector<vector<int>>& cnt, string& target, int i, int j, int n, int m) {
        if (j == m) return 1;
        if (n - i < m - j) return 0;
        if (dp[i][j] != -1) return dp[i][j];
        
        long val = cnt[i][target[j] - 'a'] * dfs(dp, cnt, target, i + 1, j + 1, n, m);
        val += dfs(dp, cnt, target, i + 1, j, n, m);
        val %= mod;
        return dp[i][j] = val;;
    }
    
    
    int numWays(vector<string>& words, string target) {
        int n = words[0].length();
        vector<vector<int>> cnt(n, vector<int>(26, 0));
        for (const auto& s: words) {
            for (int i = 0; i < n; i++) {
                cnt[i][s[i]-'a']++;
            }
        }
        
        int m = target.length();
        vector<vector<long>> dp(n, vector<long>(m, -1));
        return dfs(dp, cnt, target, 0, 0, n, m);
    }
};

image.png

小结

我是人肉真值表打印机,暴力题我根本不怕。

背包问题根据题目特殊点构造状态转移方程的表示方法,虽然一直是两个变量,但是变量的意义在不断变化。

参考链接