字符串OJ
1. LeetCode第415题—字符串相加
class Solution {
public:
string addStrings(string num1, string num2) {
string ret;
int end1 = num1.size()-1;
int end2 = num2.size()-1;
int carry = 0;
while(end1 >= 0 || end2 >= 0)
{
//在end1和end2本身也是应该可以等于字符串下标0那个位置的
int x1 = end1 >= 0 ? num1[end1]-'0': 0;
int x2 = end2 >= 0 ? num2[end2]-'0': 0;
int sum = x1 + x2 + carry;
ret += to_string(sum % 10);
carry = sum / 10;
--end1;
--end2;
}
if(carry ==1)
ret += to_string(carry);
reverse(ret.begin(),ret.end());
return ret;
}
};
2. LeetCode第43题—字符串相乘
解题思路:对于字符串相乘来说,两个数相乘的结果不会超过mn的个数其中m表示第一个字符串的字符个数,n表示第二个字符串的个数(换句话说,9999的结果最多就是4位数的结果),此时我们采用的方法是不用直接的上来就进位,而是让所有的数都相加,最后再求这个进位,且我这里采用的是倒着的计算方式。最后一个难点就是要把倒过来的时候作为首位的0去除掉。
class Solution {
public:
string multiply(string num1, string num2) {
vector<int> v1;
vector<int> v2;
int m = num1.size();
int n = num2.size();
for(int i = m-1;i>=0;--i)
{
v1.push_back(num1[i]-'0');
}
for(int j = n-1;j>=0;--j)
{
v2.push_back(num2[j]-'0');
}
//先把两个字符串中的数都按照倒叙的方式一个个存储在数组中,其次我们知道不管如何,两个数相乘
//都不可能超过他们两者和的位数m+n
vector<int> ret(m+n,0);
for(int i = 0;i<m;++i)
{
for(int j = 0;j<n;++j)
{
ret[i+j] += v1[i] * v2[j];
}
}
//上面的两层for循环就已经可以求出现在所有的每个位置的结果了
int carry = 0;
for(int i = 0;i<ret.size();++i)
{
carry += ret[i];
ret[i] = carry % 10;
carry /= 10;
}
//然后上面的就是结果,但是现在是倒着的
int k = ret.size()-1;
//这一步的主要目的就是为了去除整数倒过来以后的0
//为什么这里不能够k>=0
//只有这样才能在0*0的时候不出现错误
//不然的话就直接返回的是空字符串
while(k > 0 && !ret[k])
--k;
string str;
while(k >= 0)
{
str += ret[k--] + '0';
}
return str;
}
};
3. LeetCode第6题—Z字形变换
解题思路:这道题就有意思了,首先就是他的思想就是触及反弹这么个意思,但是解题的过程中采用了一个标志位的方式,一下子就简化了这道题的复杂程度。但是在min函数内部,是不能够使用s.size()这么个函数的,所以我们采用int的初始化方式,最后再将字符串进行拼接就可以得到我们想要的答案。
class Solution {
public:
//行数就是numRows,但是多少列呢?
string convert(string s, int numRows) {
//这道题的核心关键在于触及反弹这里,比如说当在第一行的时候,他就应该往下走,当到最后一行的时候,就应该往上走
if(numRows == 1)
return s;
//这一句代码是什么意思?需要好好的在理一下
//你想一下如果s就两个字符,但是你此时要3行,那么也是不和规矩的
vector<string> v(min(numRows,int(s.size())));
//此时就相当于字符串拼接一样
int curRow = 0;
bool goingDown = false;
for(char c : s)
{
v[curRow] += c;
//此时我们需要改变curRow
if(curRow == 0 || curRow == numRows-1)
goingDown = !goingDown;
curRow += goingDown? 1:-1;
}
string ret;
for(string& str: v)
{
ret += str;
}
return ret;
}
};
4. LeetCode第4题—寻找两个正序数组的中位数
5. LeetCode第3题—整数反转
解题思路:这道题最难的点在于,要考虑到你在反转叠加的过程中是有可能大数溢出的,所以要提前的进行判断。
class Solution {
public:
int reverse(int x) {
int ret = 0;
while(x != 0)
{
//为什么这里使用的是ret > INT_MAX/10,而不是使用ret*10 < INT_MAX主要的原因就是,如果大数溢出了,那么直接就会崩掉了
if(ret< INT_MIN / 10 || ret > INT_MAX / 10)
{
return 0;
}
//因为你这一步ret*10的操作本身就有可能会大数溢出,所以这里要做好判断
ret = ret*10 + x % 10;
x /= 10;
}
return ret;
}
};
6. LeetCode第394题—字符串解码(重点)
在遇见‘[’的时候,把前面的数字和字符串都添加到栈里面
class Solution {
public:
string decodeString(string s) {
//借助双栈的思想,这道题还是很考验思路的有必要在做一次
//"aaa2[bc]"这里展开
//我们应该尽力首先把两个括号中间的给展开,然后在展开最外面的
//是不是可以借助栈的思想
stack<int> nums;
stack<string> strs;
int num = 0;
string res; //因为最终返回的也是一个字符串
for(int i = 0;i<s.size();++i)
{
if(s[i] >= '0' && s[i] <= '9')
{
num = num*10 + s[i]-'0';
}
else if((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z'))
{
res += s[i];
}
else if(s[i] == '[')
{
//此时就应该彻底的展开了
nums.push(num);
num = 0;
strs.push(res);
res = "";
}
else
{
//此时就是‘]’,既然是收括号了,那么就要有不一样的操作了
int times = nums.top();
nums.pop();
for(int i = 0;i<times;++i)
//这里我发现我始终有点不是很理解
//这一步相当于先处理里面括号
//这里的strs.pop()是"",循环上来一次就变为"a"
strs.top() += res;
res = strs.top(); // 什么意思
strs.pop();
}
}
return res;
}
};