LeetCode 28. Implement strStr()
int strStr(string haystack, string needle) {
const int max_num = 1024;
int shift[max_num];
int n = haystack.size(), m = needle.size();
for(int i = 0; i < max_num; i++)
shift[needle[i]] = m + 1;
for(int i = 0; i < m; i++)
shift[needle[i]] = m - i;
int s = 0, j = 0;
while(s <= n - m) {
j = 0;
while(haystack[s+j] == needle[j]) {
j++;
if(j >= m)
return s;
}
s += shift[haystack[s+m]];
}
return -1;
}
Sunday字符串匹配算法,参考博客:字符串匹配——Sunday算法
int strStr(string haystack, string needle) {
return haystack.find(needle);
}
搞事情的一行代码版本 -.-
LeetCode 14. Longest Common Prefix
string longestCommonPrefix(vector& strs) {
if(strs.size() == 0) return "";
int pre_index = -1;
bool flag = true;
for(int i = 0; i < strs[0].size(); i++) {
for(int j = 1; j < strs.size(); j++)
if(strs[j][i] != strs[0][i])
flag = false;
if(flag) pre_index = i;
else break;
}
string res = "";
for(int i = 0; i <= pre_index; i++)
res += strs[0][i];
return res;
}
思路:暴力检查,注意空值即可,时间复杂度 O(nk)。
另一种思路是Tire树,建树后检查最小的深度,比较麻烦且效率不高。
LeetCode 58. Length of Last Word
int lengthOfLastWord(string s) {
int index = s.size() - 1, len = 0;
while(index >= 0 && s[index] == ' ')
index--;
while(index >= 0 && s[index] != ' ')
index--,len++;
return len;
}
思路:反向检查,注意 1.末尾可能有多余的空格,2.字符串中无空格,3.字符串全部是空格,4.字符串为空 等可能的特殊情况即可。
LeetCode 387. First Unique Character in a String
int firstUniqChar(string s) {
int counter[26] = {0};
vector vec;
for(int i = 0; i < 26; i++)
counter[i] = -1;
for(int i = 0; i < s.size(); i++)
vec.push_back(s[i]);
for(int i = 0; i < s.size(); i++)
if(counter[s[i]-'a'] == -1)
counter[s[i]-'a'] = i;
else if(counter[s[i]-'a'] >= 0)
counter[s[i]-'a'] = -2;
for(int i = 0; i < vec.size(); i++)
if(counter[vec[i]-'a'] >= 0)
return counter[vec[i]-'a'];
return -1;
}
思路:计数器,初始化为-1,遍历字符,若计数器中为-1,则将下标添加进去,否则标记为-2(有重复的),使用一个vector来记录顺序。
int firstUniqChar(string s) {
int counter[26] = {0};
for(int i = 0; i < s.size(); i++)
counter[s[i]-'a']++;
for(int i = 0; i < s.size(); i++)
if(counter[s[i]-'a'] == 1)
return i;
return -1;
}
改进的方法:使用原有的字符串的顺序,而不是自己创建一个vector。看起来是我的思路被局限了呢2333
LeetCode 383.Ransom Note
bool canConstruct(string ransomNote, string magazine) {
unordered_map ran_m, mag_m;
for(int i = 0; i < ransomNote.size(); i++)
ran_m[ransomNote[i]]++;
for(int i = 0; i < magazine.size(); i++)
mag_m[magazine[i]]++;
for(auto iter = ran_m.begin(); iter != ran_m.end(); ++iter)
if(iter->second > mag_m[iter->first])
return false;
return true;
}
思路:我想到的办法是使用计数器进行计数,之后再检查。
bool canConstruct(string ransomNote, string magazine) {
int counter[26] = {0};
for(int i = 0; i < magazine.size(); i++)
counter[magazine[i]-'a']++;
for(int i = 0; i < ransomNote.size(); i++)
if(--counter[ransomNote[i]-'a'] < 0)
return false;
return true;
}
讨论区发现的改进方法:使用数组代替unordered_map,时间从40ms减少到20ms
LeetCode 344. Reverse String
void reverseString(vector& s) {
int start = 0, end = s.size() - 1;
while(start < end) {
swap(s[start], s[end]);
start++, end--;
}
}
一行代码版本:
void reverseString(vector& s) {
reverse(s.begin(), s.end());
}
LeetCode 151.Reverse Words in a String
void reverseWords(string &s) {
bool flag = true;
for(int i = 0; i < s.size(); i++)
if(s[i] != ' ')
flag = false;
if(flag == true) {
s = "";
return ;
}
string str = "";
stack st;
int len = s.size();
for(int i = 0; i < len; i++){
if(s[i] == ' '){
if(str != "" && str != " ")
st.push(str);
str = "";
}
else
str += s[i];
}
if(str != "" && str != " ")
st.push(str);
str = "";
while(!st.empty()) {
str += st.top();
st.pop();
if(!st.empty())
str += ' ';
}
s = str;
}
流氓题目,养成看题的好习惯qwq
LeetCode 557. Reverse Words in a String III
string reverseWords(string s) {
int start = 0, end = 0;
while(start < s.size()) {
while(start < s.size() && s[start] == ' ')
start++;
end = start;
while(end < s.size() && s[end] != ' ')
end++;
reverse(s.begin()+start, s.begin()+end);
start = end;
}
return s;
}
思路:获取每个单词的首尾位置,反转。
LeetCode 345. Reverse Vowels of a String
bool isVowels(char c) {
if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
return true;
if(c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U')
return true;
return false;
}
string reverseVowels(string s) {
int start = 0, end = s.size() - 1;
while(start < end) {
while(start < s.size() && !isVowels(s[start]))
start++;
while(end < s.size() && !isVowels(s[end]))
end--;
if(start < end)
swap(s[start], s[end]);
start++, end--;
}
return s;
}
思路:找到每个元音字母的位置后反转,注意判断,还有大小写都是要考虑的emmm
def reverseVowels(self, s):
vowels = re.findall('(?i)[aeiou]', s)
return re.sub('(?i)[aeiou]', lambda m: vowels.pop(), s)
跑个题:在评论区看到的使用Python正则表达式的写法,niubi
LeetCode 205. Isomorphic Strings
bool isIsomorphic(string s, string t) {
unordered_map s_t, t_s;
for(int i = 0; i < s.size(); i++)
if(s_t[s[i]] == 0 && t_s[t[i]] == 0) {
s_t[s[i]] = t[i];
t_s[t[i]] = s[i];
}
else if(s_t[s[i]] != t[i])
return false;
return true;
}
思路:建立相互映射的Hash表,检查是否匹配,使用数组代替unordered_map速度会略快一些。
LeetCode 290. Word Pattern
bool wordPattern(string pattern, string str) {
vector words;
stringstream ss(str);
while(ss >> str)
words.push_back(str);
if(pattern.size() != words.size()) return false;
unordered_map p_s;
unordered_map s_p;
for(int i = 0; i < pattern.size(); i++)
if(p_s[pattern[i]] == "" && s_p[words[i]] == 0) {
p_s[pattern[i]] = words[i];
s_p[words[i]] = pattern[i];
}
else if(p_s[pattern[i]] != words[i])
return false;
return true;
}
思路:同上一题,这次貌似无法用数组优化了2333
LeetCode 242. Valid Anagram
bool isAnagram(string s, string t) {
if(s.size() != t.size()) return false;
int counter[26] = {0};
for(int i = 0; i < s.size(); i++)
counter[s[i]-'a']++;
for(int i = 0; i < t.size(); i++)
if(--counter[t[i]-'a'] < 0)
return false;
return true;
}
思路:计数器A上去就完事了
LeetCode 49. Group Anagrams
vector> groupAnagrams(vector& strs) {
unordered_map> map;
for(const auto& str : strs){
string s = str;
sort(begin(s), end(s));
map[s].push_back(move(str));
}
vector> result;
for(auto& kv : map)
result.push_back(move(kv.second));
return result;
}
思路:还是hash表,可以考虑计算Hash值而不是对字符串进行排序,思路是使用26个素数,对一个字符串中的字符对应的素数进行连乘。
参考思路:Java beat 100%!!! use prime number