LeetCode字符串 string(共112题)
Posted zhangwanying
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode字符串 string(共112题)相关的知识,希望对你有一定的参考价值。
【3】Longest Substring Without Repeating Characters (2019年1月22日,复习)
【5】Longest Palindromic Substring (2019年1月22日,复习)
【6】ZigZag Conversion (2019年1月22日,复习)
【8】String to Integer (atoi) (2019年1月22日,复习)
【10】Regular Expression Matching (2019年1月22日,复习)
【12】Integer to Roman (2019年1月22日,复习)
【13】Roman to Integer (2019年1月22日,复习)
罗马数字转换成整数。
题解:用一个map来存储映射关系。
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 };
【14】Longest Common Prefix (2019年1月22日,复习)
给了一组单词,由小写字母构成,找他们的公共前缀,返回这个字符串。
题解:可以暴力解,可以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 };
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 };
【17】Letter Combinations of a Phone Number (2019年1月22日,复习)
给了一个座机电话, 给了一个数字的字符串 digits,返回所有的数字对应的字母排列。
题解: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 };
【20】Valid Parentheses (2019年1月22日,复习)
Given a string containing just the characters \'(\'
, \')\'
, \'{\'
, \'}\'
, \'[\'
and \']\'
, determine if the input string is valid. 判断一个字符串中的括号是不是合法的。
题解:用栈做。
代码不贴了。
【22】Generate Parentheses (2019年1月22日,复习)
【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 };
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 (2018年11月27日,高精度乘法) (2019年3月5日更新)
给了两个string类型的数字,num1 和 num2, 用string的形式返回 num1 * num2。(num1, num2 的长度都小于等于110)
题解:我们可以不做翻转的操作,从 num1 和 num2 的末尾开始计算,num1[i], num2[j] 的乘积要放在 nums[i+j+1] 的位置,进位放在 nums[i+j] 的位置。返回结果的字符串的长度肯定是 nums1.size() + nums2.size() 的长度。
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 };
【44】Wildcard Matching
【49】Group Anagrams (2019年1月23日,谷歌tag复习)
给了一个单词列表,给所有的异构词分组。
Input: ["eat", "tea", "tan", "ate", "nat", "bat"],
Output:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]
题解:我的解法,hashmap + sort。不是最优秀的解法。还有什么用 26个素数代替法,这个更快吧。
代码不贴了。
【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日, 原地翻转字符串)
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复习)
给定一个字符串 s,返回它最长的子串的长度,子串要求只能有两个distinct characters。
题解:sliding window。(time complexity is O(N))
1 class Solution { 2 public: 3 以上是关于LeetCode字符串 string(共112题)的主要内容,如果未能解决你的问题,请参考以下文章