字符串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;
    }
};
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值