【LeetCode】字符串 string(共112题)
【3】Longest Substring Without Repeating Characters?(2019年1月22日,復(fù)習(xí))
【5】Longest Palindromic Substring?(2019年1月22日,復(fù)習(xí))
【6】ZigZag Conversion?(2019年1月22日,復(fù)習(xí))
【8】String to Integer (atoi)?(2019年1月22日,復(fù)習(xí))
【10】Regular Expression Matching?(2019年1月22日,復(fù)習(xí))
?
【12】Integer to Roman?(2019年1月22日,復(fù)習(xí))
?
【13】Roman to Integer?(2019年1月22日,復(fù)習(xí))
羅馬數(shù)字轉(zhuǎn)換成整數(shù)。
題解:用一個(gè)map來(lái)存儲(chǔ)映射關(guān)系。
1 class Solution { 2 public: 3 int romanToInt(string s) { 4 const int n = s.size(); 5 initMap(); 6 int idx = 0; 7 int ret = 0; 8 while (idx < n) { 9 if (idx + 1 == n) { 10 string temp = string(1, s[idx]); 11 ret += mp[temp]; 12 idx++; 13 continue; 14 } 15 string str = s.substr(idx, 2); 16 if (mp.find(str) != mp.end()) { 17 ret += mp[str]; 18 idx += 2; 19 } else { 20 string temp = string(1, s[idx]); 21 ret += mp[temp]; 22 idx++; 23 } 24 } 25 return ret; 26 } 27 unordered_map<string, int> mp; 28 void initMap() { 29 mp["IV"] = 4, mp["IX"] = 9; 30 mp["XL"] = 40, mp["XC"] = 90; 31 mp["CD"] = 400, mp["CM"] = 900; 32 mp["I"] = 1, mp["V"] = 5, mp["X"] = 10, 33 mp["L"] = 50, mp["C"] = 100, mp["D"] = 500, 34 mp["M"] = 1000; 35 } 36 }; View Code?
【14】Longest Common Prefix?(2019年1月22日,復(fù)習(xí))
給了一組單詞,由小寫字母構(gòu)成,找他們的公共前綴,返回這個(gè)字符串。
題解:可以暴力解,可以trie樹。?
1 class Solution { 2 public: 3 string longestCommonPrefix(vector<string>& strs) { 4 if(strs.empty()) return ""; 5 for(int i=0; i<strs[0].size(); ++i){ 6 for(int j=1; j<strs.size(); ++j){ 7 if(strs[0][i] != strs[j][i]){ 8 return strs[0].substr(0,i); 9 } 10 } 11 } 12 return strs[0]; 13 } 14 }; View Code 1 class Solution { 2 public: 3 struct TrieNode { 4 char c; 5 vector<TrieNode*> children; 6 bool isEndingChar = false; 7 int cntChildrenNotNull = 0; 8 TrieNode(char t): c(t) { 9 children = vector<TrieNode*>(26, nullptr); 10 } 11 }; 12 class Trie { 13 public: 14 void insert(string s) { 15 TrieNode * node = root; 16 for (int i = 0; i < s.size(); ++i) { 17 char c = s[i]; 18 if (node->children[c-'a'] == nullptr) { 19 node->children[c-'a'] = new TrieNode(c); 20 node->cntChildrenNotNull++; 21 } 22 node = node->children[c-'a']; 23 } 24 node->isEndingChar = true; 25 return; 26 } 27 string getCommonPrefix() { 28 TrieNode* node = root; 29 string ret = ""; 30 while (node->cntChildrenNotNull == 1 && node->isEndingChar == false) { 31 for (int i = 0; i < 26; ++i) { 32 if (node->children[i]) { 33 node = node->children[i]; 34 break; 35 } 36 } 37 ret += string(1, node->c); 38 } 39 return ret; 40 } 41 TrieNode* root = new TrieNode('/'); 42 }; 43 string longestCommonPrefix(vector<string>& strs) { 44 const int n = strs.size(); 45 Trie trie; 46 for (auto s : strs) { 47 if (s.empty()) { 48 return s; 49 } 50 trie.insert(s); 51 } 52 return trie.getCommonPrefix(); 53 } 54 }; View Code?
【17】Letter Combinations of a Phone Number?(2019年1月22日,復(fù)習(xí))
給了一個(gè)座機(jī)電話, 給了一個(gè)數(shù)字的字符串 digits,返回所有的數(shù)字對(duì)應(yīng)的字母排列。
題解:map + dfs
1 class Solution { 2 public: 3 vector<string> letterCombinations(string digits) { 4 n = digits.size(); 5 if (n == 0) { return vector<string>{}; } 6 initMap(); 7 string s = ""; 8 dfs(digits, 0, s); 9 return ret; 10 } 11 int n; 12 unordered_map<int, vector<string>> mp; 13 vector<string> ret; 14 void dfs(string digits, int cur, string& s) { 15 if (cur == n) { 16 ret.push_back(s); 17 return; 18 } 19 int num = digits[cur] - '0'; 20 for (auto ele : mp[num]) { 21 string ori = s; 22 s += ele; 23 dfs(digits, cur + 1, s); 24 s = ori; 25 } 26 return; 27 } 28 void initMap() { 29 mp[2] = {"a", "b", "c"}; 30 mp[3] = {"d", "e", "f"}; 31 mp[4] = {"g", "h", "i"}; 32 mp[5] = {"j", "k", "l"}; 33 mp[6] = {"m", "n", "o"}; 34 mp[7] = {"p", "q", "r", "s"}; 35 mp[8] = {"t", "u", "v"}; 36 mp[9] = {"w", "x", "y", "z"}; 37 } 38 }; View Code?
【20】Valid Parentheses?(2019年1月22日,復(fù)習(xí))
Given a string containing just the characters?'(',?')',?'{',?'}',?'['?and?']', determine if the input string is valid. 判斷一個(gè)字符串中的括號(hào)是不是合法的。
題解:用棧做。
代碼不貼了。
【22】Generate Parentheses?(2019年1月22日,復(fù)習(xí))
?
【28】Implement strStr()? (算法群,2018年11月4日,練習(xí)kmp)
實(shí)現(xiàn)在字符串 s 中找到 模式串 p, (kmp)
題解:暴力O(N*M) 可以解, kmp O(N+M) 也可以解 ,kmp務(wù)必再深入理解一下 next 數(shù)組的求法。不然面試不給筆記看就涼涼了。(還有一個(gè)注意點(diǎn)是 p 為空串的時(shí)候要特判)
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; ) { // 判斷條件要不要取等號(hào),然后下面做了++i, ++j, for循環(huán)里面就別做了,尷尬,這都能錯(cuò) 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?(2018年11月27日,高精度乘法) (2019年3月5日更新)
給了兩個(gè)string類型的數(shù)字,num1 和 num2, 用string的形式返回 num1 * num2。(num1, num2 的長(zhǎng)度都小于等于110)
題解:我們可以不做翻轉(zhuǎn)的操作,從 num1 和 num2 的末尾開始計(jì)算,num1[i], num2[j]? 的乘積要放在 nums[i+j+1] 的位置,進(jìn)位放在 nums[i+j] 的位置。返回結(jié)果的字符串的長(zhǎng)度肯定是 nums1.size() + nums2.size() 的長(zhǎng)度。
1 class Solution { 2 public: 3 string multiply(string num1, string num2) { 4 const int size1 = num1.size(), size2 = num2.size(); 5 vector<int> nums(size1 + size2, 0); 6 for (int i = size1 - 1; i >= 0; --i) { 7 for (int j = size2 - 1; j >= 0; --j) { 8 int temp = (num1[i] - '0') * (num2[j] - '0') + (nums[i+j+1]); 9 nums[i+j+1] = temp % 10; 10 nums[i+j] += temp / 10 ; 11 } 12 } 13 string res = ""; 14 for (auto num : nums) { 15 if (num == 0 && res.empty()) { 16 continue; 17 } 18 res += num + '0'; 19 } 20 if (res.empty()) { res = "0"; } 21 return res; 22 } 23 }; View Code?
【44】Wildcard Matching?
?
【49】Group Anagrams?(2019年1月23日,谷歌tag復(fù)習(xí))
給了一個(gè)單詞列表,給所有的異構(gòu)詞分組。
Input: ["eat", "tea", "tan", "ate", "nat", "bat"],
Output:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]?
題解:我的解法,hashmap + sort。不是最優(yōu)秀的解法。還有什么用 26個(gè)素?cái)?shù)代替法,這個(gè)更快吧。
代碼不貼了。
?
【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日, 原地翻轉(zhuǎn)字符串)
?Input: "the sky is blue",
Output:?"blue is sky the".
題解:用stringstream能做。?
1 class Solution { 2 public: 3 void reverseWords(string &s) { 4 stringstream iss(s); 5 string temp; 6 iss >> s; 7 while (iss >> temp) { 8 s = temp + " " + s; 9 } 10 if (isspace(s[0])) {s = "";} 11 return; 12 } 13 };?
【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?(2019年1月29日,谷歌tag復(fù)習(xí))
給定一個(gè)字符串 s,返回它最長(zhǎng)的子串的長(zhǎng)度,子串要求只能有兩個(gè)distinct characters。
題解:sliding window。(time complexity is O(N))?
1 class Solution { 2 public: 3 int lengthOfLongestSubstringTwoDistinct(string s) { 4 const int n = s.size(); 5 int ans = 0; 6 int begin = 0, end = 0, cnt = 0; 7 unordered_map<char, int> mp; 8 while (end < n) { 9 mp[s[end]]++; 10 if (mp[s[end]] == 1) { 11 ++cnt; 12 } 13 if (cnt <= 2) { 14 ans = max(ans, end - begin + 1); 15 } 16 while (cnt > 2) { 17 mp[s[begin]]--; 18 if (mp[s[begin]] == 0) { 19 --cnt; 20 } 21 ++begin; 22 } 23 end++; 24 } 25 return ans; 26 } 27 }; View Code??
【161】One Edit Distance?(2018年11月24日,刷題數(shù))
給了兩個(gè)字符串 s 和 t,問 s 能不能通過(guò) 增加一個(gè)字符, 刪除一個(gè)字符,替換一個(gè)字符 這三種操作里面的任意一個(gè)變成 t。能的話返回 true, 不能的話返回 false。
題解:感覺是基礎(chǔ)版的編輯距離。直接通過(guò)模擬來(lái)做。beats 36%。時(shí)間復(fù)雜度是 O(N).
1 class Solution { 2 public: 3 bool isOneEditDistance(string s, string t) { 4 if (s == t) {return false;} 5 const int ssize = s.size(), tsize = t.size(); 6 int cnt = 0; 7 if (ssize == tsize) { //check replace; 8 int idx = findfirstidx(s, t); 9 if (idx == ssize || s.substr(idx+1) == t.substr(idx+1)) { 10 return true; 11 } 12 } else if (ssize == tsize - 1) { //check insert 13 int idx = findfirstidx(s, t); 14 if (idx == tsize || s.substr(idx) == t.substr(idx+1)) { 15 return true; 16 } 17 18 } else if (ssize == tsize + 1){ //check delete 19 int idx = findfirstidx(s, t); 20 if (idx == ssize || s.substr(idx+1) == t.substr(idx)) { 21 return true; 22 } 23 } 24 return false; 25 } 26 inline int findfirstidx (string s, string t) { 27 const int ssize = s.size(), tsize = t.size(); 28 int tot = min(ssize, tsize); 29 for (int i = 0; i < tot; ++i) { 30 if (s[i] != t[i]) { 31 return i; 32 } 33 } 34 return max(ssize, tsize); 35 } 36 }; View Code?
【165】Compare Version Numbers?(2019年5月5日, 字符處理類型的題目)
比較兩個(gè)字符串版本號(hào)的大小。input 是 version1 和 version2。
比較規(guī)則是: ‘.’ 作為分隔符,如果同一層級(jí)的 version1 的number 小于 version2 的 number,返回 -1, 反之,如果大于,返回 1. 如果相等的話,繼續(xù)比較下一個(gè)層級(jí)。
題解:直接模擬法做。時(shí)間復(fù)雜度是O(N).
1 class Solution { 2 public: 3 int compareVersion(string version1, string version2) { 4 int size1 = version1.size(), size2 = version2.size(); 5 int p1 = 0, p2 = 0; 6 int num1 = 0, num2 = 0; 7 while (p1 < size1 || p2 < size2) { 8 if (p1 < size1 && version1[p1] == '.') {++p1;} 9 if (p2 < size2 && version2[p2] == '.') {++p2;} 10 while (p1 < size1 && isdigit(version1[p1])) { 11 num1 = num1 * 10 + (version1[p1] - '0'); 12 ++p1; 13 } 14 while (p2 < size2 && isdigit(version2[p2])) { 15 num2 = num2 * 10 + (version2[p2] - '0'); 16 ++p2; 17 } 18 if (num1 < num2) {return -1;} 19 if (num1 > num2) {return 1;} 20 num1 = 0, num2 = 0; 21 } 22 return 0; 23 } 24 }; View Code?
【186】Reverse Words in a String II?(2018年11月8日, 原地翻轉(zhuǎn)字符串)
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.題解:無(wú)。
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日,周五,算法群)
給了一個(gè)字符串 S,為了使得 S 變成回文串可以在前面增加字符,在增加最少的字符的前提下返回新的回文 S。
題解:我的做法跟昨天的題一樣(366)就是找從第一個(gè)字符開始最長(zhǎng)的回文串,然后把后面的那小段翻轉(zhuǎn)一下,拼到前面。時(shí)間復(fù)雜度是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應(yīng)該還有更好的解法:(學(xué)習(xí)學(xué)習(xí)學(xué)習(xí))。
?
【227】Basic Calculator II?(2019年3月18日)
給了一個(gè)字符串,包含數(shù)字,+,-,*,/,和空格,求字符串表達(dá)式的值。
?
Example 1:
?
Input: "3+2*2" Output: 7?
Example 2:
?
Input: " 3/2 " Output: 1?
Example 3:
?
Input: " 3+5 / 2 " Output: 5?
題解:本題大爺他們說(shuō)用狀態(tài)機(jī)的方法來(lái)做。狀態(tài)機(jī)的方法就是遍歷字符串,如果碰到 digit 應(yīng)該怎么做,如果碰到 + - * / 應(yīng)該怎么做,如果碰到 空格 應(yīng)該怎么做。
用一個(gè) vector<int> 做為 cache 緩存前面的只用 +,- 的值。
?
1 class Solution { 2 public: 3 int calculate(string s) { 4 const int n = s.size(); 5 int num = 0; 6 char sign = '+'; 7 vector<int> cache; 8 for (int i = 0; i < n; ++i) { 9 if (isdigit(s[i])) { 10 num = num * 10 + (s[i] - '0'); 11 } 12 if (i == n-1 || !isdigit(s[i]) && s[i] != ' '){ 13 if (sign == '+') {cache.push_back(num);} 14 if (sign == '-') {cache.push_back(-num);} 15 if (sign == '*' || sign == '/') { 16 int last = cache.back(); 17 cache.pop_back(); 18 if (sign == '*') {cache.push_back(last * num);} 19 else if (sign == '/') {cache.push_back(last / num);} 20 } 21 num = 0; 22 if (!isdigit(s[i])) { sign = s[i]; } 23 } 24 } 25 int res = 0; 26 for (auto& e : cache) { 27 res += e; 28 } 29 return res; 30 } 31 }; View Code?
【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] 這個(gè)新的字符串是回文串。
題解:這題WA出了天際。因?yàn)閙ap似乎一旦訪問了某個(gè)不存在的key,這個(gè)key就變的存在了。。一開始我想暴力,暴力超時(shí),暴力時(shí)間的時(shí)間復(fù)雜度是O(N^2*K)。后來(lái)認(rèn)真思考了一下一個(gè)字符串是怎么變成回文的。如果一個(gè)字符串word,他的長(zhǎng)度是n,如果它的前半段 word[0..j] 是個(gè)回文串,那么我們需要匹配它后面那段 word[j+1..n-1], 我們把后半段reverse一下, 查找字符串集合(map)里面有沒有對(duì)應(yīng)的這段。同理,如果它的后半段 word[j+1..n-1] 是個(gè)回文串,那么我們把前半段 reverse一下,在 map 里面查找有沒有前半段就可以了。特別注意這個(gè)前半段和后半段都可以包含空串,所以 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}; 這個(gè)不能放在外面,不然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?聽說(shuō)這題還能用 trie 解,有空要看答案啊。
?
【340】Longest Substring with At Most K Distinct Characters?(2019年1月29日,谷歌tag復(fù)習(xí))
類似題:159. Longest Substring with At Most 2 Distinct Characters, sliding window 一模一樣的。時(shí)間復(fù)雜度是O(N)?
1 class Solution { 2 public: 3 int lengthOfLongestSubstringKDistinct(string s, int k) { 4 const int n = s.size(); 5 if (n <= k) {return n;} 6 int begin = 0, end = 0, cnt = 0; 7 unordered_map<char, int> mp; 8 int ans = 0; 9 while (end < n) { 10 mp[s[end]]++; 11 if (mp[s[end]] == 1) { 12 ++cnt; 13 } 14 if (cnt <= k) { 15 ans = max(ans, end - begin + 1); 16 } 17 while (cnt > k) { 18 mp[s[begin]]--; 19 if (mp[s[begin]] == 0) { 20 --cnt; 21 } 22 ++begin; 23 } 24 ++end; 25 } 26 return ans; 27 } 28 }; View Code?
【344】Reverse String?(2018年12月3日,第一次review,ko)
逆序一個(gè)字符串。
題解:直接reverse,或者 2 pointers
1 class Solution { 2 public: 3 string reverseString(string s) { 4 int start = 0, end = s.size() - 1; 5 while (start < end) { 6 swap(s[start++], s[end--]); 7 } 8 return s; 9 } 10 }; View Code?
【345】Reverse Vowels of a String?(2018年12月4日,第一次review,ko)?
逆序一個(gè)字符串的元音字母。
題解:2 pointers
1 class Solution { 2 public: 3 string reverseVowels(string s) { 4 set<char> setVowels = {'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'}; 5 int left = 0, right = s.size()-1; 6 while (left < right) { 7 while (setVowels.find(s[left]) == setVowels.end()) {++left;} 8 while (setVowels.find(s[right]) == setVowels.end()) {--right;} 9 if (left < right) { //這里需要再次判斷 10 swap(s[left++], s[right--]); 11 } 12 } 13 return s; 14 } 15 }; View Code?
【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?(2019年2月12日)
壓縮一個(gè)字符數(shù)組,"aaa" -> "a3", "bb" -> "b2", "c" -> "c"。要求 in-place。space復(fù)雜度為O(1).
題解:用指針做。用一個(gè)index指針記錄當(dāng)前新字符串的末尾的位置。
1 class Solution { 2 public: 3 int compress(vector<char>& chars) { 4 const int n = chars.size(); 5 int idx = 0; 6 int begin = 0, end = 0, cnt = 0; 7 while (end < n) { 8 if (chars[begin] == chars[end]) { 9 ++cnt; ++end; 10 } 11 if (end == n || (end < n && chars[begin] != chars[end])) { 12 chars[idx++] = chars[begin]; 13 if (cnt > 1) { 14 string s = to_string(cnt); 15 for (auto c : s) { chars[idx++] = c; } 16 } 17 begin = end; 18 cnt = 0; 19 } 20 } 21 return idx; 22 } 23 }; View Code?
【459】Repeated Substring Pattern?
?
【468】Validate IP Address?(2018年12月7日)
判斷一個(gè)字符串是不是有效的 IP 地址,區(qū)分 IPv4 和 IPv6, 都不是的話返回 Neither。IPv4 的判斷很簡(jiǎn)單,就是用 ‘.’ 隔開的四段數(shù)字,然后每段數(shù)字都在0~255中間,數(shù)字沒有前導(dǎo) 0。 IPv6 的判斷比較麻煩,是八段用 ‘:’ 隔開是數(shù)字,每段數(shù)字都是四位十六進(jìn)制數(shù)。四位數(shù)字如果有前置 0 的話,可以省略,以及大小寫都可以忽略不同。
題解:比較復(fù)雜的模擬題。我用 getline 分割字符串,注意如果 它已經(jīng)有 7 個(gè) ‘:’ 分割八段十六進(jìn)制數(shù)之后,如果在尾部還有一個(gè) ‘:’ ,那么這個(gè)要特判。?
1 #define NEITHER "Neither" 2 #define IPV4 "IPv4" 3 #define IPV6 "IPv6" 4 5 class Solution { 6 public: 7 string validIPAddress(string IP) { 8 if (IP.find(':') != string::npos) { 9 return checkIPV6(IP); 10 } 11 return checkIPV4(IP); 12 } 13 string checkIPV4(string IP) { 14 int cnt = 0; 15 string word; 16 stringstream ss; 17 ss << IP; 18 if (IP.front() == '.' || IP.back() == '.') {return NEITHER;} 19 while (getline(ss, word, '.')) { 20 cnt++; 21 if (word.size() > 3 || word.empty()) {return NEITHER;} 22 for (int i = 0; i < word.size(); ++i) { 23 if (i == 0 && word[i] == '0' && word.size() > 1 || !isdigit(word[i])) { 24 return NEITHER; 25 } 26 } 27 int num = stoi(word); 28 if (num < 0 || num > 255) {return NEITHER;} 29 } 30 if (cnt != 4) { 31 return NEITHER; 32 } 33 return IPV4; 34 } 35 string checkIPV6(string IP) { 36 int cnt = 0; 37 string word; 38 stringstream ss; 39 ss << IP; 40 if (IP.front() == ':' || IP.back() == ':') {return NEITHER;} 41 while (getline(ss, word, ':')) { 42 cnt++; 43 printf("word = %s \n", word.c_str()); 44 if (word.size() > 4 || word.empty()) {return NEITHER;} 45 for (int i = 0; i < word.size(); ++i) { 46 char c = word[i]; 47 if (!isalnum(c) || c > 'f' && c <= 'z' || c > 'F' && c <= 'Z') { 48 return NEITHER; 49 } 50 } 51 } 52 if (cnt != 8) { 53 return NEITHER; 54 } 55 return IPV6; 56 } 57 }; View Code??
【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?(2018年11月27日)
給了兩個(gè)字符串,代表兩個(gè) complex, 返回這兩個(gè)complex 的乘積(用字符串表示)。
題解:見math分類:https://www.cnblogs.com/zhangwanying/p/9790007.html
?
【539】Minimum Time Difference?(2019年2月11日)
給了一個(gè)字符串list,代表時(shí)間,返回最小的時(shí)間差(分鐘為單位)。
Input: ["23:59","00:00"] Output: 1?題解:先排序,然后兩兩相鄰的相減。還有第一個(gè)和最后一個(gè)相減。
1 class Solution { 2 public: 3 int findMinDifference(vector<string>& timePoints) { 4 sort(timePoints.begin(), timePoints.end()); 5 int ret = calDiff(timePoints[0], timePoints.back()); 6 for (int i = 0; i < timePoints.size() - 1; ++i) { 7 ret = min(ret, calDiff(timePoints[i], timePoints[i+1])); 8 } 9 return ret; 10 } 11 int calDiff(string s1, string s2) { 12 int num1 = trans(s1), num2 = trans(s2); 13 if (num1 < num2) { swap(num1, num2); } 14 return min(num1 - num2, num2 + 1440 - num1); 15 } 16 int trans(string s) { 17 int hour = stoi(s.substr(0, 2)); 18 int min = stoi(s.substr(3)); 19 return hour * 60 + min; 20 } 21 }; View Code?
【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?(2019年3月3日,H)
給定一個(gè)字符串 N, 求距離 N 最近的回文數(shù)。
題解:唔,這個(gè)題看了awice的思路。就是說(shuō),我們先把這個(gè)數(shù)分成前面一半和后面一半,比如“23456”,一半就是“234”,用前面一半分別 +{-1, 0 ,1}, 然后生成對(duì)應(yīng)的回文(注意原數(shù)字長(zhǎng)度的奇偶性)。這樣能生成3個(gè)candidate。
但是其實(shí)還有兩個(gè)數(shù)字,就是比給定數(shù)字長(zhǎng)度少一位的最大回文,9999...999,和比給定數(shù)字長(zhǎng)度多一位的最小回文,10...01。一共五個(gè)candidate。
如果candidate中有N本身,就忽略掉。從candidate中選出距離最近的那個(gè)。
1 class Solution { 2 public: 3 string nearestPalindromic(string n) { 4 const int size = n.size(); 5 string strHalf = n.substr(0, (size + 1)/ 2); 6 long long half = stoll(strHalf); 7 set<string> st; 8 long long biggest = pow(10LL, size) + 1, smallest = pow(10LL, size - 1) - 1; 9 st.insert(to_string(smallest)); 10 st.insert(to_string(biggest)); 11 for (int i = -1; i <= 1; ++i) { 12 string p = to_string(half + i); 13 string pp = p; 14 if (size & 1) { 15 pp += string(p.rbegin() + 1, p.rend()); 16 } else { 17 pp += string(p.rbegin(), p.rend()); 18 } 19 st.insert(pp); 20 } 21 st.erase(n); 22 string res = ""; 23 long long absMinDiff = LLONG_MAX; 24 for (auto& s : st) { 25 long long num = stoll(s), target = stoll(n); 26 if (abs(num - target) < absMinDiff) { 27 res = s; 28 absMinDiff = abs(num - target); 29 } else if (abs(num - target) == absMinDiff && num < target) { 30 res = s; 31 } 32 } 33 return res; 34 } 35 }; View Code?
【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?(2019年2月12日)
輸入是一個(gè)字符串,問字符串最多刪除一個(gè)字符,看能不能變成回文字符串。
題解:2 pointers 先遍歷,找到第一個(gè)失配的地方,然后分別從左右去查找跳過(guò)這個(gè)字符,剩下的字符串是不是能成回文。
1 class Solution { 2 public: 3 bool validPalindrome(string s) { 4 int begin = 0, end = s.size() - 1; 5 while (begin < end) { 6 if (s[begin] != s[end]) { 7 if (isValid(s, begin+1, end) || isValid(s, begin, end-1)) { 8 return true; 9 } 10 return false; 11 } 12 ++begin, --end; 13 } 14 return true; 15 } 16 bool isValid(string s, int begin, int end) { 17 while (begin < end) { 18 if (s[begin++] != s[end--]) {return false;} 19 } 20 return true; 21 } 22 }; View Code?
【681】Next Closest Time?(2019年1月29日,谷歌tag復(fù)習(xí))
給了一個(gè)字符串,代表時(shí)間,HH:MM,返回用當(dāng)前數(shù)字組成的合法的下一個(gè)時(shí)間。There is no limit on how many times a digit can be reused.
Input: "19:34" Output: "19:39" Explanation: The next closest time choosing from digits 1, 9, 3, 4, is 19:39, which occurs 5 minutes later. It is not 19:33, because this occurs 23 hours and 59 minutes later. Input: "23:59" Output: "22:22" Explanation: The next closest time choosing from digits 2, 3, 5, 9, is 22:22. It may be assumed that the returned time is next day's time since it is smaller than the input time numerically.題解:思路就是先把所有的四個(gè)數(shù)字存下來(lái),從最小的(分針)開始往前找,如果找到了比當(dāng)前位置更大的一個(gè)數(shù)的話,就用這個(gè)更大的數(shù)字去代替當(dāng)前的數(shù)字。(前提是這個(gè)更大的數(shù)字代替完了之后這個(gè)時(shí)間得合法。)如果找到最大的位置都沒有找到的話,那就用最小的數(shù)字生成一個(gè)第二天的時(shí)間來(lái)作為新的數(shù)字。
1 class Solution { 2 public: 3 string nextClosestTime(string time) { 4 set<int> st; 5 int minn = 10; 6 for (int i = 0; i < 5; ++i) { 7 if (isdigit(time[i])) { 8 int t = time[i] - '0'; 9 minn = min(t, minn); 10 st.insert(t); 11 } 12 } 13 if (st.size() == 1) {return time;} //invalid 14 string ret = time; 15 for (int i = 4; i >= 0; --i) { 16 char c = ret[i]; 17 int t = c - '0'; 18 auto iter = upper_bound(st.begin(), st.end(), t); 19 if (iter == st.end()) {continue;} 20 if (i == 0 && *iter > 2) { 21 continue; 22 } 23 if (i == 1 && *iter > 4 && ret[0] == '2') { 24 continue; 25 } 26 if (i == 3 && *iter > 5) { 27 continue; 28 } 29 ret[i] = (*iter) + '0'; 30 for (int k = i + 1; k < 5; ++k) { 31 if (isdigit(ret[k])) { 32 ret[k] = minn + '0'; 33 } 34 } 35 break; 36 } 37 if (ret == time) { 38 for (auto& c : ret) { 39 if (isdigit(c)) { 40 c = minn + '0'; 41 } 42 } 43 } 44 return ret; 45 46 } 47 }; View Code?
【686】Repeated String Match?
【696】Count Binary Substrings?
【709】To Lower Case?
?
【722】Remove Comments?(2019年2月16日, M)
給了一個(gè)字符串的數(shù)組,每個(gè)字符串代碼一行代碼,里面'//', '/*', '*/' 分別代表一行和多行注釋。返回去掉注釋后的代碼段。
題解:用兩個(gè)bool變量記錄,inline記錄是否當(dāng)前在//注釋里面,inBlock記錄是否當(dāng)前在 /**/ 里面。然后業(yè)務(wù)邏輯比較一下。
1 class Solution { 2 public: 3 vector<string> removeComments(vector<string>& source) { 4 vector<string> res; 5 bool inBlock = false; 6 string s = ""; 7 for (auto& line : source) { 8 const int n = line.size(); 9 bool inLine = false; 10 for (int i = 0; i < n; ++i) { 11 if (i + 1 < n && line[i] == '/') { 12 if (line[i+1] == '/' && !inBlock) { 13 inLine = true; 14 } else if (line[i+1] == '*' && !inLine && !inBlock) { 15 ++i, inBlock = true; 16 } else if (!inBlock && !inLine) { 17 s += string(1, line[i]); 18 } 19 } else if (i + 1 < n && line[i] == '*' && line[i+1] == '/') { 20 if (inBlock) { 21 ++i, inBlock = false; 22 } else if (!inLine){ 23 s += string(1, line[i]); 24 } 25 } else { 26 if (inBlock || inLine) {continue;} 27 s += string(1, line[i]); 28 } 29 } 30 if (!inBlock && !s.empty()) { 31 res.push_back(s); 32 s.clear(); 33 } 34 } 35 return res; 36 } 37 }; View Code?
【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?(2018年11月27日)
給了兩個(gè)字符串 S 和 T, S中最多有 26個(gè)小寫字母,給 T 重新排序,如果字母 x, y 在 S 中出現(xiàn),且在 T 中出現(xiàn),如果在 S 中 x 出現(xiàn)在 y 之前, 那么在 T 中 x 也要出現(xiàn)在 y 之前。沒有在 S 中出現(xiàn)的字符就隨便放哪里都可以。
題解:直接 unordered_map
1 class Solution { 2 public: 3 string customSortString(string S, string T) { 4 const int n = T.size(); 5 unordered_map<char, int> mp; 6 for (int i = 0; i < n; ++i) { 7 mp[T[i]]++; 8 } 9 string ret; 10 for (auto c : S) { 11 if (mp.find(c) == mp.end() || mp[c] == 0) {continue;} 12 ret += string(mp[c], c); 13 mp[c] = 0; 14 } 15 for (auto ele : mp) { 16 if (ele.second > 0) { 17 ret += string(ele.second, ele.first); 18 } 19 } 20 return ret; 21 } 22 }; View Code?
【800】Similar RGB Color?
【804】Unique Morse Code Words?
?
【809】Expressive Words?(2019年2月13日,google tag)
給了一個(gè)word S和一個(gè)word list,問word list中有多少pattern符合S。一個(gè) pattern w 符合 S 的條件是,w extend之后可以變成 S。w 中的一個(gè)字母可以extend成三個(gè)或者三個(gè)以上相同的字母。問word list中有多少個(gè)這樣的pattern。
題解:我的解法時(shí)間復(fù)雜度是O(NM),空間復(fù)雜度使用了一個(gè)map,還是比較高的。我的解法的說(shuō)明如下:對(duì)于S中每一個(gè)小段重復(fù)序列,計(jì)算當(dāng)前字符重復(fù)了多少次。根據(jù)不同重復(fù)的次數(shù)得到pattern中的相同字符的范圍,然后去對(duì)比pattern。
1 class Solution { 2 public: 3 int expressiveWords(string S, vector<string>& words) { 4 const int n = S.size(); 5 unordered_map<string, int> mp; 6 for (auto& w : words) { mp[w] = 0; } 7 int begin = 0, end = 0, cnt = 0; 8 int res = 0; 9 while (end < n) { 10 while (end < n && S[begin] == S[end]) { 11 ++end; 12 } 13 cnt = end - begin; 14 pair<int, int> range(0, 0); 15 if (cnt <= 2) { 16 range = make_pair(cnt, cnt); 17 } else { 18 range = make_pair(1, cnt + 1 - 3); 19 } 20 res = 0; 21 for (auto& p : mp) { 22 string pattern = p.first; 23 int start = p.second, end1 = start, size = pattern.size(); 24 if (start < 0) {continue;} 25 while (end1 < size && pattern[end1] == pattern[start]) { 26 ++end1; 27 } 28 int sameSize = end1 - start; 29 if (sameSize >= range.first && sameSize <= range.second) { 30 p.second = end1; 31 ++res; 32 } else { 33 p.second = -1; 34 } 35 } 36 begin = end; 37 } 38 return res; 39 } 40 }; View Code還有l(wèi)ee215的解法。寫的很短,也很好理解。需要好好復(fù)習(xí)學(xué)習(xí)。
用word list中每個(gè)單詞和S做一個(gè)比較,比較規(guī)則如下:
Loop through all words.?check(string S, string W)?checks if?W?is stretchy to?S.
In?check?function, use two pointer:
?
【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?
轉(zhuǎn)載于:https://www.cnblogs.com/zhangwanying/p/9885334.html
總結(jié)
以上是生活随笔為你收集整理的【LeetCode】字符串 string(共112题)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2017年第八届蓝桥杯【C++省赛B组】
- 下一篇: 课堂练习----二维数组