1. 程式人生 > >【LeetCode】字串 string(共112題)

【LeetCode】字串 string(共112題)

【3】Longest Substring Without Repeating Characters 

【5】Longest Palindromic Substring 

【6】ZigZag Conversion 

【8】String to Integer (atoi) 

【10】Regular Expression Matching 

【12】Integer to Roman 

【13】Roman to Integer 

【14】Longest Common Prefix 

【17】Letter Combinations of a Phone Number 

【20】Valid Parentheses 

【22】Generate Parentheses 

 

【28】Implement strStr()  (演算法群,2018年11月4日,練習kmp)

實現在字串 s 中找到 模式串 p, (kmp)

題解:暴力O(N*M) 可以解, kmp O(N+M) 也可以解 ,kmp務必再深入理解一下 next 陣列的求法。不然面試不給筆記看就涼涼了。(還有一個注意點是 p 為空串的時候要特判)

 1 class Solution {
 2 public:
 3     int strStr(string haystack, string needle) {
 4         return kmp(haystack, needle);
 5     }
 6     int kmp(string& s, string& p) {
 7         const int n = s.size(), m = p.size();
 8         if (m == 0) {return 0;} //p empty
 9         vector<int
> next = getNext(p); 10 int i = 0, j = 0; 11 while (i < n && j < m) { 12 if (j == -1 || s[i] == p[j]) { 13 ++i, ++j; 14 } else { 15 j = next[j]; 16 } 17 } 18 if (j == m) { 19 return i - j; 20 } 21 return -1; 22 } 23 vector<int> getNext(string& p) { 24 const int n = p.size(); 25 vector<int> next(n, 0); 26 next[0] = -1; 27 int j = 0, k = -1; 28 while (j < n - 1) { 29 if (k == -1 || p[j] == p[k]) { 30 ++k, ++j; 31 next[j] = p[j] == p[k] ? next[k] : k; 32 } else { 33 k = next[k]; 34 } 35 } 36 return next; 37 } 38 };
kmp
 1 //暴力解法 O(N*M)
 2 class Solution {
 3 public:
 4     int strStr(string haystack, string needle) {
 5         const int n = haystack.size(), m = needle.size();
 6         if (m == 0) {return 0;}
 7         for (int i = 0; i + m <= n; ) {  // 判斷條件要不要取等號,然後下面做了++i, ++j, for迴圈裡面就別做了,尷尬,這都能錯
 8             int j; int oldi = i;
 9             for (j = 0; j < m;) {
10                 if (haystack[i] == needle[j]) {
11                     ++i, ++j;
12                 } else {
13                     break;
14                 }
15             }
16             if (j == m) {
17                 return i - j;
18             } else {
19                 i = oldi + 1;
20             }
21         }
22         return -1;
23     }
24 };
暴力

 

【30】Substring with Concatenation of All Words 

【32】Longest Valid Parentheses 

【38】Count and Say 

【43】Multiply Strings 

【44】Wildcard Matching 

【49】Group Anagrams 

【58】Length of Last Word 

【65】Valid Number 

【67】Add Binary 

【68】Text Justification 

【71】Simplify Path 

【72】Edit Distance 

【76】Minimum Window Substring 

【87】Scramble String 

【91】Decode Ways 

【93】Restore IP Addresses 

【97】Interleaving String 

【115】Distinct Subsequences 

【125】Valid Palindrome 

【126】Word Ladder II 

【151】Reverse Words in a String (2018年11月8日, 原地翻轉字串)

 

【157】Read N Characters Given Read4 

【158】Read N Characters Given Read4 II - Call multiple times 

【159】Longest Substring with At Most Two Distinct Characters 

【161】One Edit Distance 

【165】Compare Version Numbers 

 

【186】Reverse Words in a String II (2018年11月8日, 原地翻轉字串)

Given an input string , reverse the string word by word. 

Example:
Input:  ["t","h","e"," ","s","k","y"," ","i","s"," ","b","l","u","e"]
Output: ["b","l","u","e"," ","i","s"," ","s","k","y"," ","t","h","e"]

Note: 
A word is defined as a sequence of non-space characters.
The input string does not contain leading or trailing spaces.
The words are always separated by a single space.

題解:無。

 1 class Solution {
 2 public:
 3     void reverseWords(vector<char>& str) {
 4         reverse(str.begin(), str.end());
 5         const int n = str.size();
 6         int p1 = 0, p2 = 0;
 7         while (p2 < n) {
 8             while (p1 < n && str[p1] == ' ') {p1++;}
 9             p2 = p1;
10             while (p2 < n && str[p2] != ' ') {p2++;}
11             reverse(str.begin() + p1, str.begin() + p2);
12             p1 = p2;
13         }
14         return;
15     }
16 };
View Code

 

【214】Shortest Palindrome (2018年11月2日,週五,演算法群)

給了一個字串 S,為了使得 S 變成迴文串可以在前面增加字元,在增加最少的字元的前提下返回新的迴文 S。

題解:我的做法跟昨天的題一樣(366)就是找從第一個字元開始最長的迴文串,然後把後面的那小段翻轉一下,拼到前面。時間複雜度是O(N^2)

 1 //類似的題目可以見 336 Palindrome Pairs
 2 class Solution {
 3 public:
 4     string shortestPalindrome(string s) {
 5         const int n = s.size();
 6         string ans = "";
 7         for (int j = n; j >= 0; --j) {
 8             if (isPalindrome(s, 0, j-1)) {
 9                 string str = s.substr(j);
10                 reverse(str.begin(), str.end());
11                 ans = str + s;
12                 break;
13             }
14         }
15         return ans;
16     }
17     bool isPalindrome(const string& s, int start, int end) { //[start, end]
18         while (start < end) {
19             if (s[start] != s[end]) {return false;}
20             start++, end--;
21         }
22         return true;
23     }
24 };
View Code

應該還有更好的解法:(學習學習學習)。

【227】Basic Calculator II 

【249】Group Shifted Strings 

【271】Encode and Decode Strings 

【273】Integer to English Words 

【293】Flip Game 

【336】Palindrome Pairs (2018年11月1日,週四,演算法群)

給了一組字串words,找出所有的pair (i,j),使得 words[i] + words[j] 這個新的字串是迴文串。

題解:這題WA出了天際。因為map似乎一旦訪問了某個不存在的key,這個key就變的存在了。。一開始我想暴力,暴力超時,暴力時間的時間複雜度是O(N^2*K)。後來認真思考了一下一個字串是怎麼變成迴文的。如果一個字串word,他的長度是n,如果它的前半段 word[0..j] 是個迴文串,那麼我們需要匹配它後面那段 word[j+1..n-1], 我們把後半段reverse一下, 查詢字串集合(map)裡面有沒有對應的這段。同理,如果它的後半段 word[j+1..n-1] 是個迴文串,那麼我們把前半段 reverse一下,在 map 裡面查詢有沒有前半段就可以了。特別注意這個前半段和後半段都可以包含空串,所以 j 的範圍是[0, n]。

 1 class Solution {
 2 public:
 3     vector<vector<int>> palindromePairs(vector<string>& words) {
 4         const int n = words.size();
 5         unordered_map<string, int> mp;
 6         for (int i = 0; i < n; ++i) {
 7             mp[words[i]] = i;
 8         }
 9         vector<vector<int>> ans;
10         set<vector<int>> st;
11         for (int i = 0; i < n; ++i) {
12             string word = words[i];
13             int size = word.size();
14             for (int j = 0; j <= size; ++j) {
15                 if (isPalindrome(word, 0, j-1)) {
16                     string str = word.substr(j);
17                     reverse(str.begin(), str.end());
18                     //vector<int> candidate = vector<int>{mp[str], i};  這個不能放在外面,不然mp[str]可能不存在
19                     if (mp.find(str) != mp.end() && mp[str] != i) {
20                         vector<int> candidate = vector<int>{mp[str], i};
21                         if (st.find(candidate) == st.end()) {
22                             ans.push_back(candidate);
23                             st.insert(candidate);
24                         }
25                     }
26                 }
27                 if (isPalindrome(word, j, size-1)) {
28                     string str = word.substr(0, j);
29                     reverse(str.begin(), str.end());
30                     //vector<int> candidate = vector<int>{i, mp[str]};
31                     if (mp.find(str) != mp.end() && mp[str] != i) {
32                         vector<int> candidate = vector<int>{i, mp[str]};
33                         if (st.find(candidate) == st.end()) {
34                             ans.push_back(candidate);
35                             st.insert(candidate);
36                         }
37                     }
38                 }
39             }
40         }
41         return ans;
42     }
43     bool isPalindrome(const string& word, int start, int end) { // [start, end]
44         while (start < end) {
45             if (word[start++] != word[end--]) { return false; }
46         }   
47         return true;
48     }
49 };
View Code

 聽說這題還能用 trie 解,有空要看答案啊。

【340】Longest Substring with At Most K Distinct Characters 

【344】Reverse String 

【345】Reverse Vowels of a String 

【383】Ransom Note 

【385】Mini Parser 

【387】First Unique Character in a String 

【408】Valid Word Abbreviation 

【434】Number of Segments in a String 

【443】String Compression 

【459】Repeated Substring Pattern 

【468】Validate IP Address 

【520】Detect Capital 

【521】Longest Uncommon Subsequence I 

【522】Longest Uncommon Subsequence II 

【527】Word Abbreviation 

【536】Construct Binary Tree from String 

【537】Complex Number Multiplication 

【539】Minimum Time Difference 

【541】Reverse String II 

【544】Output Contest Matches 

【551】Student Attendance Record I 

【553】Optimal Division 

【555】Split Concatenated Strings 

【556】Next Greater Element III 

【557】Reverse Words in a String III 

【564】Find the Closest Palindrome 

【583】Delete Operation for Two Strings 

【591】Tag Validator 

 

【606】Construct String from Binary Tree 

2018年11月14日,樹的分類裡面做了:https://www.cnblogs.com/zhangwanying/p/6753328.html

 

【609】Find Duplicate File in System 

【616】Add Bold Tag in String 

【632】Smallest Range 

【635】Design Log Storage System 

【647】Palindromic Substrings 

【657】Robot Return to Origin 

【678】Valid Parenthesis String 

【680】Valid Palindrome II 

【681】Next Closest Time 

【686】Repeated String Match 

【696】Count Binary Substrings 

【709】To Lower Case 

【722】Remove Comments 

【730】Count Different Palindromic Subsequences 

【736】Parse Lisp Expression 

【758】Bold Words in String 

【761】Special Binary String 

【767】Reorganize String 

【770】Basic Calculator IV 

【772】Basic Calculator III 

【788】Rotated Digits 

【791】Custom Sort String 

【800】Similar RGB Color 

【804】Unique Morse Code Words 

【809】Expressive Words 

【816】Ambiguous Coordinates 

【819】Most Common Word 

【824】Goat Latin 

【831】Masking Personal Information 

【833】Find And Replace in String 

【842】Split Array into Fibonacci Sequence 

【848】Shifting Letters 

【856】Score of Parentheses 

【859】Buddy Strings 

【890】Find and Replace Pattern 

【893】Groups of Special-Equivalent Strings 

【899】Orderly Queue