class Solution {
public:
string replaceSpace(string s) {
string res;
for(int i=0; i<s.size(); i++)
{
if(s[i]==' ')
res += "%20";
else
res += s[i];
}
return res;
}
};
时间复杂度 O(N):遍历字符串 s,每轮修改 res;
空间复杂度 O(N):创建一个新的字符串变量存储修改后的字符串。
s
,获取空格的数量 space_cnt
;s
的大小为 s.size() + space_cnt * 2
;s
,如果遇到的不是空格,则直接填充,如果遇到的是空格,则填充“%20”。class Solution {
public:
string replaceSpace(string s) {
int space_cnt = 0;
int old_size = s.size();
// 获取空格的数量
for(int i=0; i<s.size(); i++)
{
if(s[i] == ' ') space_cnt++;
}
// 修改字符串的长度
s.resize(old_size + space_cnt * 2);
// 倒序修改
for(int i=s.size()-1, j=old_size-1; i>=0, j>=0; i--, j--)
{
if(s[j] == ' ')
{
s[i] = '0';
s[i-1] = '2';
s[i-2] = '%';
i-=2;
}
else
{
s[i] = s[j];
}
}
return s;
}
};
时间复杂度 O(N):遍历字符串 s;
空间复杂度 O(1):原地修改。
class Solution {
public:
string reverseLeftWords(string s, int n) {
string tmp1 = s.substr(0, n), tmp2 = s.substr(n, s.size()-n);
return tmp2 + tmp1;
}
};
时间复杂度 O(N):切片复杂度为O(N);
空间复杂度 O(N):两个切片返回的临时对象长度之和为 N。
ed
表示的是 有效字符串的后一位class Solution {
public:
bool isNum(char c)
{
if(c<='9' && c>='0') return true;
return false;
}
bool isDecimal(string s)
{
int idx = 0;
if(s[0] == '+' || s[0] == '-')
s = s.substr(1, s.size()-1);
if(s == "" || s == ".") return false;
int point_pos = s.find('.');
if(point_pos == 0)
{
// 开头是点
for(int i=1; i<s.size(); i++)
{
if(!isNum(s[i])) return false;
}
}
if(point_pos == s.size()-1)
{
// 结尾是点
for(int i=0; i<s.size()-1; i++)
{
if(!isNum(s[i])) return false;
}
}
// 点在中间
for(int i=0; i<point_pos;i++)
{
if(!isNum(s[i])) return false;
}
for(int i=point_pos+1; i<s.size();i++)
{
if(!isNum(s[i])) return false;
}
return true;
}
bool isInteger(string s)
{
int idx = 0;
if(s[0] == '+' || s[0] == '-')
s = s.substr(1, s.size()-1);
if(s == "") return false;
while(isNum(s[idx]))
idx++;
if(idx==s.size()) return true;
return false;
}
bool isNumber(string s) {
int n = s.size();
int idx = 0;
int st = 0, ed = 0;
int e_pos = s.find('e')!=s.npos ? s.find('e') : s.find('E');
bool flag = false;
while(s[idx] == ' ')
{
idx++;
}
st = idx;
while(idx < s.size() && s[idx] != ' ')
{
idx++;
}
ed = idx; // 有效字符串的后一位
// 之后是不是全是空格
for(int i=idx; i<s.size(); i++)
{
if(s[i] != ' ')
return false;
}
// 有没有 e/E
if(e_pos == s.npos)
{ // 没有 e/E,只有一个整数或一个小数
flag = isInteger(s.substr(st, ed-st)) || isDecimal(s.substr(st, ed-st));
}
else
{
flag = isInteger(s.substr(st, e_pos-st)) || isDecimal(s.substr(st, e_pos-st));
flag = flag && (isInteger(s.substr(e_pos+1, ed-e_pos-1)));
}
return flag;
}
};
时间复杂度 O(N):遍历字符串 s;
空间复杂度 O(N):有限变量。
创建状态,绘制有限状态自动机
本质上是利用 map 实现了一个状态转移矩阵。
class Solution {
public:
enum State{
STATE_INITIAL,
STATE_INT_SIGN,
STATE_INTEGER,
STATE_POINT,
STATE_POINT_WITHOUT_INT,
STATE_FRACTION,
STATE_EXP,
STATE_EXP_SIGN,
STATE_EXP_NUMBER,
STATE_END
};
enum CharType{
CHAR_NUMBER,
CHAR_EXP,
CHAR_POINT,
CHAR_SIGN,
CHAR_SPACE,
CHAR_ILLEGAL
};
CharType toCharType(char ch)
{
if(ch>='0' && ch<='9') return CHAR_NUMBER;
else if(ch=='e' || ch=='E') return CHAR_EXP;
else if(ch=='.') return CHAR_POINT;
else if(ch=='+' || ch=='-') return CHAR_SIGN;
else if(ch==' ') return CHAR_SPACE;
else return CHAR_ILLEGAL;
}
bool isNumber(string s) {
unordered_map<State, unordered_map<CharType, State> > transfer
{
{
STATE_INITIAL, {
{CHAR_SPACE, STATE_INITIAL},
{CHAR_NUMBER, STATE_INTEGER},
{CHAR_SIGN, STATE_INT_SIGN},
{CHAR_POINT, STATE_POINT_WITHOUT_INT}
}
},
{
STATE_INT_SIGN, {
{CHAR_NUMBER, STATE_INTEGER},
{CHAR_POINT, STATE_POINT_WITHOUT_INT}
}
},
{
STATE_INTEGER, {
{CHAR_NUMBER, STATE_INTEGER},
{CHAR_POINT, STATE_POINT},
{CHAR_EXP, STATE_EXP},
{CHAR_SPACE, STATE_END}
}
},
{
STATE_POINT, {
{CHAR_NUMBER, STATE_FRACTION},
{CHAR_EXP, STATE_EXP},
{CHAR_SPACE, STATE_END}
}
},
{
STATE_FRACTION, {
{CHAR_EXP, STATE_EXP},
{CHAR_SPACE, STATE_END},
{CHAR_NUMBER, STATE_FRACTION}
}
},
{
STATE_POINT_WITHOUT_INT, {
{CHAR_NUMBER, STATE_FRACTION}
}
},
{
STATE_EXP, {
{CHAR_SIGN, STATE_EXP_SIGN},
{CHAR_NUMBER, STATE_EXP_NUMBER}
}
},
{
STATE_EXP_SIGN, {
{CHAR_NUMBER, STATE_EXP_NUMBER}
}
},
{
STATE_EXP_NUMBER, {
{CHAR_NUMBER, STATE_EXP_NUMBER},
{CHAR_SPACE, STATE_END}
}
},
{
STATE_END, {
{CHAR_SPACE, STATE_END}
}
}
};
int n = s.size();
State st = STATE_INITIAL;
for(int i=0;i<n;i++)
{
CharType tmp = toCharType(s[i]);
if(transfer[st].find(tmp) == transfer[st].end())
{
return false;
}
else
{
st = transfer[st][tmp];
}
}
return st == STATE_INTEGER || st == STATE_POINT || st == STATE_FRACTION || st == STATE_EXP_NUMBER || st == STATE_END;
}
};
时间复杂度 O(N):遍历字符串 s;
空间复杂度 O(1):有限状态转移矩阵。
枚举 - enum
将一组整形常量组织在一起,常用来作为数据的标识。
class Solution {
public:
bool isNum(char c)
{
if(c >= '0' && c <= '9') return true;
return false;
}
int strToInt(string str) {
int n = str.size();
if(str == "") return 0;
int st = 0, ed = 0, idx = 0;
while(idx<n && str[idx]==' ')
{
idx++;
}
if(idx == n) return 0;
st = idx;
if(!isNum(str[st]) && str[st]!='-' && str[st]!='+') return 0;
idx++;
while(idx<n && isNum(str[idx]))
{
idx++;
}
ed = idx;
if(str[st] == '-')
{
int ans = 0;
for(int i=st+1; i<ed; i++)
{
if(ans<INT_MIN/10) return -2147483648;
if(ans==INT_MIN/10 && str[i]>'8') return -2147483648;
ans=ans*10 - (str[i]-'0');
}
// ans*=-1;
return ans;
}
else
{
int ans = 0;
if(str[st] == '+') st++;
cout<<st<<" "<<ed<<endl;
for(int i=st; i<ed; i++)
{
if(ans>INT_MAX/10) return 2147483647;
if(ans==INT_MAX/10 && str[i]>'7') return 2147483647;
ans=ans*10 + (str[i]-'0');
}
return ans;
}
}
};
时间复杂度 O(N):遍历字符串 s;
空间复杂度 O(1):有限变量。
越界判断:(参考评论区)
- 除以10,如果除以10的结果和上一次的计算结果不同,意味发生越界。
int temp = res * 10 + (chars[i] - '0');
if (temp / 10 != res) return sign == 1? Integer.MAX_VALUE : Integer.MIN_VALUE;
res = temp;
- 在乘10之前先与 INT_MAX/10 或 INT_MIN/10 比较,因为每一轮 temp 都会进行乘10操作,所以可以在乘10之前进行判断。
for(int i=st+1; i<ed; i++)
{
if(ans<INT_MIN/10) return -2147483648;
if(ans==INT_MIN/10 && str[i]>'8') return -2147483648;
ans=ans*10 - (str[i]-'0');
}
for(int i=st; i<ed; i++)
{
if(ans>INT_MAX/10) return 2147483647;
if(ans==INT_MAX/10 && str[i]>'7') return 2147483647;
ans=ans*10 + (str[i]-'0');
}
string
的 +
与 +=
(+=
要比 +
高效)str = str + a;
:先将等号右边的两个 string
对象内容相加,并且创建一个新的 string
对象接收他们的和的赋值,再把结果赋值给左边的 str
。
str += a;
:直接将等号右边的 string
对象内容追加到左边的 string
对象后。
+
会比 +=
多创建一个对象,因此时间上和空间上的效率都会比 +=
低。
- 除以10,如果除以10的结果和上一次的计算结果不同,意味发生越界。
int temp = res * 10 + (chars[i] - '0');
if (temp / 10 != res) return sign == 1? Integer.MAX_VALUE : Integer.MIN_VALUE;
res = temp;
- 在乘10之前先与 INT_MAX/10 或 INT_MIN/10 比较,因为每一轮 temp 都会进行乘10操作,所以可以在乘10之前进行判断。
for(int i=st+1; i<ed; i++)
{
if(ans<INT_MIN/10) return -2147483648;
if(ans==INT_MIN/10 && str[i]>'8') return -2147483648;
ans=ans*10 - (str[i]-'0');
}
for(int i=st; i<ed; i++)
{
if(ans>INT_MAX/10) return 2147483647;
if(ans==INT_MAX/10 && str[i]>'7') return 2147483647;
ans=ans*10 + (str[i]-'0');
}
enum
将一组整形常量组织在一起,常用来作为数据的标识。