天天看点

LeetCode(Weekly Contest 190)题解

0. 前言

  • 中文版地址:https://leetcode-cn.com/contest/weekly-contest-190/
  • 英文版地址:https://leetcode.com/contest/weekly-contest-190/

1. 题解

1.1 5416. 检查单词是否为句中其他单词的前缀(1455. Check If a Word Occurs As a Prefix of Any Word in a Sentence)

  • 中文版题目描述:https://leetcode-cn.com/problems/check-if-a-word-occurs-as-a-prefix-of-any-word-in-a-sentence/
  • 英文版题目描述:https://leetcode.com/problems/check-if-a-word-occurs-as-a-prefix-of-any-word-in-a-sentence/
  • 思路:签到题,模拟
  • 代码如下:
class Solution {
public:
    int isPrefixOfWord(string sentence, string searchWord) {
        int len = sentence.length();
        if (sentence[len-1] != ' ') {
            sentence += " ";
            len++;
        }
        int last = 0;
        vector<string> words;
        for (int i = 1 ; i< len ; i++) {
            if (sentence[i] == ' ') {
                words.push_back(sentence.substr(last, i-last));
                last = i + 1;
            }
        }
        for (int i = 0 ; i < (int)words.size() ; i++) {
            int lv = words[i].length(), ls = searchWord.length();
            if (lv < ls)    continue;
            if (words[i].substr(0, ls) == searchWord)  return i+1;
        }
        return -1;
    }
};      

1.2 5417. 定长子串中元音的最大数目(1456. Maximum Number of Vowels in a Substring of Given Length)

  • 中文版题目描述:https://leetcode-cn.com/problems/maximum-number-of-vowels-in-a-substring-of-given-length/
  • 英文版题目描述:https://leetcode.com/problems/maximum-number-of-vowels-in-a-substring-of-given-length/
  • 思路:窗口统计,在一个大小为 k 的窗口内统计 'a'、'e'、'r'、'o'、'u' 个数
  • 暴力代码如下:
class Solution {
public:
    int maxVowels(string s, int k) {
        int len = (int)s.length(), cnt = 0, ans = 0;
        for (int i = 0 ; i < k ; i++) {
            if (s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u') {
                cnt++;
            }
        }
        ans = cnt;
        for (int i = k ; i < len ; i++) {
            if (s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u') {
                cnt++;
            }
            if (s[i-k] == 'a' || s[i-k] == 'e' || s[i-k] == 'i' || s[i-k] == 'o' || s[i-k] == 'u') {
                cnt--;
            }
            ans = max(ans, cnt);
        }
        return ans;
    }
};      

1.3 5418. 二叉树中的伪回文路径(1457. Pseudo-Palindromic Paths in a Binary Tree)

  • 中文版题目描述:https://leetcode-cn.com/problems/pseudo-palindromic-paths-in-a-binary-tree/
  • 英文版题目描述:https://leetcode.com/problems/pseudo-palindromic-paths-in-a-binary-tree/
  • 思路:遍历二叉树,用一个数组统计每条从根节点到叶子节点路径 1-9 数字的个数
    • 如果节点个数是奇数个,那么自身数量为奇数的数字个数只能为 1
    • 如果节点个数是偶数个,那么自身数量为偶数的数字个数只能为 0
    • 看某一个大神的题解,也可以通过 位运算实现,膜拜一下
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    void dfs(TreeNode* root, vector<int>& cnt, int& ans) {
        if (root->left == NULL && root->right == NULL) {
            int sum = 0, odd = 0;
            for (int i = 1 ; i <= 9 ; i++) {
                if (cnt[i] % 2) odd++;
                sum += cnt[i];
            }
            if (sum % 2 == odd)    ans++;
            return;
        }
        if (root->left) {
            cnt[root->left->val]++;
            dfs(root->left, cnt, ans);
            cnt[root->left->val]--;
        }
        if (root->right) {
            cnt[root->right->val]++;
            dfs(root->right, cnt, ans);
            cnt[root->right->val]--;
        }
    }
    int pseudoPalindromicPaths (TreeNode* root) {
        if (root == NULL)   return 0;
        vector<int> cnt = vector<int>(10, 0);
        cnt[root->val]++;
        int ans = 0;
        dfs(root, cnt, ans);
        cnt[root->val]--;
        return ans;
    }
};      

1.4 5419. 两个子序列的最大点积(1458. Max Dot Product of Two Subsequences)

  • 中文版题目描述:https://leetcode-cn.com/problems/max-dot-product-of-two-subsequences/
  • 英文版题目描述:https://leetcode.com/problems/max-dot-product-of-two-subsequences/
  • 思路:类似最长公共子序列,dp[i][j] 表示 nums1 前 i 个和 nums2 前 j 个的最大点积和,O(n^2) 复杂度
    • 注意题中要求需要为非空子序列,因此初始值不应该为 0
    • 一开始想复杂了,多加了一维表示子序列长度,结果一直超时,,想了半天恍然大明白
class Solution {
public:
    int maxDotProduct(vector<int>& nums1, vector<int>& nums2) {
        int n1 = (int)nums1.size(), n2 = (int)nums2.size(), len = min(n1, n2);
        vector<vector<int>> dp = vector<vector<int>>(n1+1, vector<int>(n2+1, -50000000));
        int ans = INT_MIN;
        for (int i = 0 ; i <= n1 ; i++) {
            dp[i][0] = 0;
        }
        for (int i = 0 ; i <= n2 ; i++) {
            dp[0][i] = 0;
        }
        for (int j = 1 ; j <= n1 ; j++) {
            for (int k = 1 ; k <= n2 ; k++) {
                if (j > 1 && k > 1) {
                    dp[j][k] = dp[j-1][k-1]; 
                }
                if (j > 1) {
                    dp[j][k] = max(dp[j][k], dp[j-1][k]);
                }
                if (k > 1) {
                    dp[j][k] = max(dp[j][k], dp[j][k-1]);
                }
                dp[j][k] = max(dp[j][k], max(dp[j-1][k-1] + nums1[j-1] * nums2[k-1], nums1[j-1] * nums2[k-1]));
                // cout << j << "<>" << k << "==" << dp[j][k] << " | " << ans << endl;
                ans = max(ans, dp[j][k]);
            } 
        }
        return ans;
    }
};      

3. 参考文献 

  • https://leetcode-cn.com/problems/pseudo-palindromic-paths-in-a-binary-tree/solution/wei-yun-suan-jie-fa-by-dnanki/
  • https://leetcode-cn.com/problems/max-dot-product-of-two-subsequences/solution/c-dong-tai-gui-hua-yi-dong-by-smilyt_/