剑指offer很多题都是数字类的和字符串的,太麻烦了...
8. 字符串转换整数 (atoi)
class Solution {
public:
int myAtoi(string str) {
if(!str.size()) return 0;
int n = str.size();
bool is_neg = false;
long long res = 0;
int i = 0;
for(; i < n; i ++)
if(str[i] == ' ') continue;
else break;
if(str[i] == '-') {is_neg = true; i ++;}
else if(str[i] == '+') i ++;
for(int j = i; j < str.size() && str[i]>='0' && str[i]<='9'; j ++)
{
if(is_neg) res = res*10 - (str[i]-'0');//因为需要在溢出时考虑正负,所以直接在循环时把正负号分开考虑
else res = res*10 + (str[i]-'0');
if(res > INT_MAX ) {return INT_MAX;}
if(res < INT_MIN) {return INT_MIN;}
i++;
}
return res;
}
};
12. 整数转罗马数字
class Solution {
public:
string intToRoman(int num) {
if(num <= 0) return "";
string res = "";
int number[13] = {1000,900,500,400,100,90,50,40,10,9,5,4,1};
string flags[13] = {"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
for(int i = 0; i < 13; i ++)
{
if(num < number[i]) continue;
while(num >= number[i])
{
res += flags[i];
num -= number[i];
}
}
return res;
}
};
13. 罗马数字转整数
class Solution {
public:
int romanToInt(string s) {
map<char,int> m = {{'I',1},{'V',5},{'X',10},{'L',50},{'C',100},{'D',500},{'M',1000}};//hash表
int res = 0;
//如果前一个数比后一个小,就减去,其余都直接加上
for(int i = 0; s[i]; i ++)
{
if(i + 1 < s.size() && m[s[i]] < m[s[i + 1]]) res -= m[s[i]];
else res += m[s[i]];
}
return res;
}
};
14. 最长公共前缀
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if(!strs.size()) return "";
int n = strs.size();
for(int i = 0; i < strs[0].size(); i ++)
{
char tmp = strs[0][i];//tmp直接在第一个数里面取,假设最长前缀就是strs[0],因为不管怎么不会超过其中任何一个的长度,后面循环遇到不满足的再跳出
for(int j = 1; j < n; j ++)
{//1.遇到其中最短长度了,0~i-1共i个数是可以的;2.遇到不等于的情况了,0~i-1共i个数是可以的
if(i == strs[j].size() || strs[j][i] != tmp ) return strs[0].substr(0, i);
}
}
return strs[0];
}
};
17. 电话号码的字母组合
class Solution {
public:
string chars[8] = {"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
vector<string> letterCombinations(string digits) {
//用循环实现搜索
if(digits.empty()) return vector<string>();
vector<string> state(1, "");
for(auto u : digits)
{
vector<string> now;
for(auto x : chars[u - '2'])//取出abc中的 a b c
for(auto s : state)//加在前面所有状态里
now.push_back(s + x);
state = now;
}
return state;
}
};
剑指 Offer 05. 替换空格
class Solution {
public:
string replaceSpace(string s) {
int len = s.size();
int cnt = 0;
for(int i = 0; i < len; i ++) if(s[i] == ' ') cnt ++;
int N = 2 * cnt;
string s2(N, ' ');
s += s2;
for(int i = len + N - 1,j = len - 1; j >= 0; i --, j --)
{
if(s[j] != ' ') s[i] = s[j];
else
{
s[i] = '0', s[-- i] = '2',s[-- i] = '%';
}
}
return s;
}
};
剑指 Offer 58 - II. 左旋转字符串
class Solution {
public:
string reverseLeftWords(string s, int n) {
string res;
for(int i = 0; i < n; i ++) res += s[i];
s.erase(0, n);
s += res;
return s;
}
};
剑指 Offer 58 - I. 翻转单词顺序
class Solution {
public:
string reverseWords(string s) {
//不开新空间,用o(n)时间和o(1)空间
//先删除前后空格
int k = 0, n = s.size(), e = n-1;
while(k < s.size() && s[k] == ' ') k++; // 去掉前面的空格
while(e >= 0 && s[e] == ' ') e--; // 去掉后面的空格
s.erase(e + 1, n - e - 1);//先删后面的空格再删前面,免得前面影响序号
s.erase(0, k);
//去掉中间空格
int siz = s.size();
for(int i = 0; i < siz; i ++)
{
int j = i;
while(s[i] == ' ' && i < siz) i++;
//两个及以上的空格
if(i > (j + 1) && i < siz) s.erase(j + 1, i - j - 1), siz = siz - (i - j - 1),i = j;
}
//1.翻转整个句子
//2.每个单词内部翻转
reverse(s.begin(), s.end());
for(int i = 0; i < s.size(); i ++)
{
int j = i;
while(s[j] !=' ' && j < s.size()) j ++;
reverse(s.begin() + i, s.begin() + j);
i = j;
}
return s;
}
};
剑指 Offer 20. 表示数值的字符串
class Solution {
public:
bool isNumber(string s) {
//去除前后空格
int i = 0;
while (i < s.size() && s[i] == ' ') i ++ ;
int j = s.size() - 1;
while (j >= 0 && s[j] == ' ') j -- ;
if (i > j) return false;
s = s.substr(i, j - i + 1);
//处理+-.
if(s[0] == '+' || s[0] == '-') s = s.substr(1);//直接到末尾子串
if(s.empty() || (s[0] == '.' && s.size() == 1)) return false;//+-.的情况
//遍历
int dot = 0,e = 0;//统计这两个值
for(int i = 0; i < s.size(); i ++)
{
if (s[i] >= '0' && s[i] <= '9');
else if (s[i] == '.')//如果是.,则前面不能有e,点的个数不能>1
{
dot ++ ;
if (e || dot > 1) return false;
}
else if (s[i] == 'e' || s[i] == 'E')//如果是e,不能是最后一个字符或者第一个字符,或者在.后面的.e情况,或者e+ e-是最后两个字符的情况
{
e ++ ;
if (i + 1 == s.size() || !i || e > 1 || i == 1 && s[0] == '.') return false;
if (s[i + 1] == '+' || s[i + 1] == '-')//e
{
if (i + 2 == s.size()) return false;
i ++ ;
}
}
else return false;
}
return true;
}
};