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/通过结果: