1. 程式人生 > >[LeetCode] Longest Word in Dictionary through Deleting 刪除後得到的字典中的最長單詞

[LeetCode] Longest Word in Dictionary through Deleting 刪除後得到的字典中的最長單詞

Given a string and a string dictionary, find the longest string in the dictionary that can be formed by deleting some characters of the given string. If there are more than one possible results, return the longest word with the smallest lexicographical order. If there is no possible result, return the empty string.

Example 1:

Input:
s = "abpcplea", d = ["ale","apple","monkey","plea"]

Output: 
"apple"

Example 2:

Input:
s = "abpcplea", d = ["a","b","c"]

Output: 
"a"

Note:

  1. All the strings in the input will only contain lower-case letters.
  2. The size of the dictionary won't exceed 1,000.
  3. The length of all the strings in the input won't exceed 1,000.

這道題給了我們一個字串,和一個字典,讓我們找到字典中最長的一個單詞,這個單詞可以通過給定單詞通過刪除某些字元得到。由於只能刪除某些字元,並不能重新排序,所以我們不能通過統計字元出現個數的方法來判斷是否能得到該單詞,而是隻能老老實實的按順序遍歷每一個字元。我們可以給字典排序,通過重寫comparator來實現按長度由大到小來排,如果長度相等的就按字母順序來排。然後我們開始遍歷每一個單詞,用一個變數i來記錄單詞中的某個字母的位置,我們遍歷給定字串,如果遍歷到單詞中的某個字母來,i自增1,如果沒有,就繼續往下遍歷。這樣如果最後i和單詞長度相等,說明單詞中的所有字母都按順序出現在了字串s中,由於字典中的單詞已經按要求排過序了,所以第一個通過驗證的單詞一定是正確答案,我們直接返回當前單詞即可,參見程式碼如下:

解法一:

class Solution {
public:
    string findLongestWord(string s, vector<string>& d) {
        sort(d.begin(), d.end(), [](string a, string b){
            if (a.size() == b.size()) return a < b;
            return a.size() > b.size();
        });
        for (string str : d) {
            int i = 0;
            for (char c : s) {
                if (i < str.size() && c == str[i]) ++i;
            }
            if (i == str.size()) return str;
        }
        return "";
    }
};

上面的方法中用到了sort排序,對於陣列中單詞的數量不是很多,但是長度特別長的情況很適用,但是如果對於單詞數量特別多,但是每個都不長的話,排序的O(nlgn)時間複雜度可能就不是最好的方法了,也可以不用排序來做。我們遍歷字典中的單詞,然後還是跟上面的方法一樣來驗證當前單詞是否能由字串s通過刪除字元來得到,如果能得到,而且單詞長度大於等於結果res的長度,我們再看是否需要更新結果res,有兩種情況是必須要更新結果res的,一個是當前單詞長度大於結果res的長度,另一種是當前單詞長度和res相同,但是字母順序小於結果res,這兩種情況下更新結果res即可,參見程式碼如下:

解法二:

class Solution {
public:
    string findLongestWord(string s, vector<string>& d) {
        string res = "";
        for (string str : d) {
            int i = 0;
            for (char c : s) {
                if (i < str.size() && c == str[i]) ++i;
            }
            if (i == str.size() && str.size() >= res.size()) {
                if (str.size() > res.size() || str < res) {
                    res = str;
                }
            }
        }
        return res;
    }
};

參考資料: