【算法設計作業】week13


30. Substring with Concatenation of All Words

題目來源:https://leetcode.com/problems/substring-with-concatenation-of-all-words/description/

思路

本道題的思路是滑動窗口,一個窗口windows在字符串S上滑動,每一個位置都檢驗窗口的內容是否滿足條件,如果滿足,則記錄這個窗口的開始位置。
而對於windows內是否滿足的判定又有技巧。因爲我們不要求次序,而只要出現過。因而可以用unordered_map記錄每個word出現的次數。這樣就不需要雙重循環來判斷,判定的複雜度降到低過O(n^2)
這裏寫圖片描n述

參考代碼

來自本題目的discussion。

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        unordered_map<string, int> counts;
        for(string word: words){
            counts[word]++;
        }
        int n = s.length(), num = words.size(), lenOfWord = words[0].length();
        vector<int> indexes;
        for(int i = 0; i < n - num*lenOfWord+1; i++) {
            unordered_map<string, int> seen;
            int j = 0;
            for(; j < num; j++) {
                string word = s.substr(i+j*len, len);
                if(counts.find(word) != counts.end()) {
                    seen[word]++;
                    if (seen[word] > counts[word]) 
                        break;
                } else {
                    break;
                }
            }
            if (j == num) indexes.push_back(i);
        }
        return indexes;
    }
};

32. Longest Valid Parentheses

題目來源:https://leetcode.com/problems/longest-valid-parentheses/description/

思路

這題非常巧妙,思路是動態規劃。
我們定義dp數組的第i個元素代表,以第s[i]終結的合法括號匹配串。顯然只有以’)’結尾的括號串纔可能合法。而以’(‘結尾的必定是不合法的,因爲括號未全部匹配,此時s[i]=0。
考慮動態規劃的update函數:
a.當遇到x()的情況時,這裏的x是一個字符串,s[i]s[i-1]匹配了,因而

dp[i] = dp[i-2]+2

。這裏,()的長度是2,而x的長度我們不用管,無關x是否合法,我們直接加,結果都是正確的。
b.當遇到xy(...)) 的時候,此處y是一個字符,我們就要看y和最後的)是否匹配。如果y),顯然是不匹配的,那麼dp[i]=0,不用管。如果y(那麼,就匹配了,則

dp[i] = dp[i-1]+dp[i-dp[i-1]-2]+2

這裏dp[i-1]就是(...)的長度,dp[i-dp[i-1]-2] 就是x長度,而不管x長度多少,因爲加上去總是正確的,原因跟a類似。而2就是最後的)和對應的(的長度。

由a,b兩種情況,我們就討論完了。照着就可以寫出狀態轉移方程了。

參考代碼

有參考本題的solution。

class Solution {
public:
    int longestValidParentheses(string s) {
        int maxans = 0;
        vector<int> dp;
        dp.resize(s.length());
        for (int i = 1; i < s.length(); i++) {
            if (s[i] == ')') {
                if (s[i - 1] == '(') {
                    dp[i] = (i >= 2 ? dp[i - 2] : 0) + 2;
                } else if (i - dp[i - 1] > 0 && s[i - dp[i - 1] - 1] == '(') {
                    dp[i] = dp[i - 1] + ((i - dp[i - 1]) >= 2 ? dp[i - dp[i - 1] - 2] : 0) + 2;
                }
                maxans = max(maxans, dp[i]);
            }
        }
        return maxans;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章