Leetcode刷题——题目8、9、10

8.字符串转换整数

解题:

class Solution {
public:
    int myAtoi(string s) {
    int i = 0;
    while (i < s.size() && s[i] == ' ')i++;   //过滤空格
    string s1;
    int k = 0;
    if (i == s.size() || (!(s[i] >= '0' || s[i] <= '9') && s[i] != '-' && s[i] != '+'))return 0;

    long ans = 0;
    //分为整数中的正数和负数情况
    if (s[i] == '-') {
        i++;
        while (i < s.size() && s[i] >= '0' && s[i] <= '9') {
            ans = ans * 10 - (s[i]-'0');    //相当于是将字符变成整数,不然输出的就是对应的ASCII码。
            i++;
            if (ans != (int)ans) return INT_MIN;  //32 位有符号整数范围 [−2的31次方,  2的31次方 − 1]
        }
    }
    else {
        if (s[i] == '+')
            i++;
        while (i < s.size() && s[i] >= '0' && s[i] <= '9') {
            cout << s[i] << "  " << ans << "  " << endl;
            ans = ans * 10 + (s[i]-'0');  //s[i]-'0'计算的就是相对字符'0'的偏移值,该偏移值正好是字符所代表的字面数值
            i++;
            
            if (ans != (int)ans)return INT_MAX;
        }
    }
    return (int)ans;
}
};

通过结果:

9.回文数

解题:

class Solution {
public:
    bool isPalindrome(int x) {
        if(x<0) return false;
        if(x>=0 && x<=9) return true;
        int temp=x,y=x;  
        long long  sum=0;
        while(temp){
            y=temp%10;
            sum=sum*10+y;
            temp=temp/10;
        }
        if(sum==x) return true;
        else return false;
    }
};

通过结果:

 另一种思路:只回文一半

class Solution {
public:
    bool isPalindrome(int x) {
    if (x < 0) return false;
    if (x >= 0 && x <= 9) return true;
    if (x % 10 == 0) return false;
    int temp = x, y = x,sum = 0;
    while (temp > sum) {
        y = temp % 10;
        temp = temp / 10;
        sum = sum * 10 + y;
    }
    if (sum == temp || sum/10==temp) return true;
    else return false; 
}
};

 10.正则表达式匹配

 

解题:

class Solution {
public:
    bool isMatch(string s, string p) {
        if(p.empty() ) return s.empty();  //当p为空的所有情况
        if(p.size()==1){   //当p长度=1的所有情况
            return ( s.size()==1 && (s[0]==p[0] || p[0]=='.') );
        }
        if(p[1]!='*'){    //当p长度>1
            if(s.empty()) return false;
            else return (s[0]==p[0] || p[0] == '.')&&isMatch(s.substr(1),p.substr(1));
        }
        while(!s.empty() && (s[0]==p[0] || p[0]=='.') ){
            if(isMatch(s,p.substr(2))) return true;
            s=s.substr(1);
        }
        return isMatch(s,p.substr(2));
    }
};

 这题不太会写,参考:
LeetCode(10):正则表达式匹配 - Ariel_一只猫的旅行 - 博客园

通过结果:

挺秃然的,肯定要优化……

优化代码:采用动态规划的思想

C++动态规划详解_Godvvvvvvv的博客-CSDN博客_c++动态规划

重点:拆分问题->定义状态并找出出状态->找到状态转换方程

class Solution {
public:
    bool isMatch(string s, string p) {
        int len1=s.size(),len2=p.size();
        vector<vector <bool>> dp(len1+1,vector <bool>(len2+1));
        //initial dp
        dp[0][0]=true;
        for(int i=1;i<len2+1;i++){
            dp[0][i]=false;
        }
        //情况1 s为空,p有*的情况
        for(int i=1;i<len2+1;i++){
            if(p[i]=='*'){
                dp[0][i+1]=dp[0][i-1];
            }
        }
        for(int i=1;i<len1+1;i++){
            for(int j=1;j<len2+1;j++){
                if(s[i-1]==p[j-1] ||p[j-1]=='.'){
                    dp[i][j]=dp[i-1][j-1];
                }
                else if(p[j-1]=='*'){
                    if(s[i-1]==p[j-2] || p[j-2]=='.'){
                        dp[i][j]=dp[i][j-2] || dp[i-1][j-2] ||dp[i-1][j];
                        //dp[i][j-2]的时候*与a抵消,这个时候a一个a都没有;
                        //dp[i-1][j-2]的时候*相当于1个a;
                        //dp[i-1][j]的时候相当于要一直往前靠拢,最后达到dp[i-1][j-2]的状态;
                    }
                    else{
                        dp[i][j]=dp[i][j-2];
                    }
                }
            }
        }
        return dp[len1][len2];
    }
};

通篇理解:dp[i][j]表示s 的前 i个字符与 ppp 中的前 j个字符是否能够匹配

①初始化部分:为什么只初始化二维数组的第一行。因为第一行的意思是当s.size()==0时,p.size()==0,则为true,不然基础条件,p.size()>0时,返回false(当然不是所有情况);

 ②其中一种情况,s.size()==0,但是p=“a*”的这种情况,p是可以为空的,也就是说*消灭掉前面的a,就可以让p跟s匹配上了。

第一轮的时候p[i]是p的第二个字符,这个如果等于* ,那么dp的第3个空间,即dp[2]就和它往前数两个的空间是一样的。因为dp[i1-1]代表的就是p[i-2]的空间。

③匹配上了,这是个好情况

④没匹配上,但是如果是* ,就有可能匹配上;如果是字母没匹配上,直接false;

如果当前s的字符可以和*的前面一个字符(可以是字母,或者“.”),那就分别对应4种情况:

(图里面写的有点误导人,a1的时候应该是* 和 a相互抵消的时候;a2是*不起作用,只有一个a的时候;a3就是a有两个及其以上的时候)

举例子:a1:a-aa*;a2:aa-aa*;a3:aaa-aa*

⑤还有一种情况是*让前面的字母消失:

 

 最后备注:手绘图不是自己的。来源:力扣https://leetcode-cn.com/problems/regular-expression-matching/solution/shou-hui-tu-jie-wo-tai-nan-liao-by-hyj8/通过结果:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值