leetcode思路总结反思(string篇)
28. Implement strStr()
最初代码(有细微的问题):
int strStr(string haystack, string needle) {
if(needle.empty())
return 0;
if(haystack.empty())
return -1;
for(int i=0;i<=haystack.size()-needle.size();i++)
{
if(haystack.substr(i,needle.size())==needle)
return i;
}
return -1;
}
该代码问题在for循环语句中的i<=haystack.size()-needle.size()部分,因为string::size()返回的是一种无符号类型数,相减也不会变为负数,所以一旦遇到诸如haystack=“aaaa”,needle=“aaaaa”,这种情况,便会出错。所以求string长度的代码应在之前求出并且用int表示。
正确代码:
int strStr(string haystack, string needle) {
int len_h = haystack.size();
int len_n = needle.size();
if(needle.empty())
return 0;
if(haystack.empty())
return -1;
for(int i=0;i<=len_h-len_n;i++)
{
if(haystack.substr(i,len_n)==needle)
return i;
}
return -1;
}
此外,该题用上述方法来做速度较慢,更快的方法为:KMP
reverse专题:(不限string的reverse,还包括linked list等)
344. Reverse String
维持两个指针
class Solution {
public:
void reverseString(vector<char>& s) {
int i = 0;
int j = s.size()-1;
while(i<j)
{
swap(s[i++],s[j--]);
}
}
};
345.Reverse Vowels of a String
同样的维持两个指针,但是会跳过非元音字母
class Solution {
public:
string reverseVowels(string s) {
unordered_set<char> all{'a','e','i','o','u','A','E','I','O','U'};
int i = 0;
int j = s.size()-1;
while(i<j)
{
while(all.find(s[i])==all.end()&&i<j)
i++;
while(all.find(s[j])==all.end()&&i<j)
j--;
if(i<j)
swap(s[i++],s[j--]);
}
return s;
}
};
541. Reverse String II
有一些技巧,原理大致相同
class Solution {
public:
string reverseStr(string s, int k) {
int len = s.size();
for(int i=0;i<len;i+=2*k)
{
for(int lb=i,ub=min(len-1,lb+k-1);lb<ub;lb++,ub--)
{
swap(s[lb],s[ub]);
}
}
return s;
}
};
93. Restore IP Addresses
如下为最开始的代码,本题要注意什么是合法的IP Addresses,本题中合法的IP Addresses是指:
①:具有四个元素
②:每个元素范围是0<=X<=255
③:一个元素如果不为0,那么这个元素不带任何前导零,例如“010”,“01”都不合法,若元素为零,只能有单独的一个零,例如“00”,“000”都不合法
class Solution {
public:
void dfs(vector<string> & res,string tmp,int n,string s)
{
if(n==4)
{
if(s.empty())
res.push_back(tmp);
return;
}
for(int i=1;i<=3&&i<=s.size();i++)
{
int ctx = atoi(s.substr(0,i).c_str());
if(0<=ctx&&ctx<=255)
{
if(!tmp.empty())
dfs(res,tmp+'.'+s.substr(0,i),n+1,s.substr(i));
else
dfs(res,tmp+s.substr(0,i),n+1,s.substr(i));
}
}
}
vector<string> restoreIpAddresses(string s) {
vector<string> res;
string tmp;
dfs(res,tmp,0,s);
return res;
}
};
上述代码没有考虑到第三条规则,下面的代码在dfs中新加入了以下两行,用于适应上述第三条规则。
if(i==1&&ctx==0)
break;
class Solution {
public:
void dfs(vector<string> & res,string tmp,int n,string s)
{
if(n==4)
{
if(s.empty())
res.push_back(tmp);
return;
}
for(int i=1;i<=3&&i<=s.size();i++)
{
int ctx = atoi(s.substr(0,i).c_str());
if(0<=ctx&&ctx<=255)
{
if(!tmp.empty())
dfs(res,tmp+'.'+s.substr(0,i),n+1,s.substr(i));
else
dfs(res,tmp+s.substr(0,i),n+1,s.substr(i));
}
if(i==1&&ctx==0)
break;
}
}
vector<string> restoreIpAddresses(string s) {
vector<string> res;
string tmp;
dfs(res,tmp,0,s);
return res;
}
};