47 求1+2+3…+n
题目描述
求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
示例1
输入:
5
返回值:
15
思路:
题目限制不能使用乘除法和条件判断语句,所以只能使用递归来计算
class Solution {
public:
int Sum_Solution(int n) {
if(n==1)return n;
return n+Sum_Solution(n-1);
}
};
48 不用加减乘除做加法
题目描述
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
示例1
输入:
1,2
返回值:
3
思路:
不能用四则运算符号,所以要使用位运算。
两个整数&运算,等于1的位需要向前进一位,两个整数^运算,等于1的是不需要进位的位
把进位后的数和不需要进位的数再次&运算,循环执行直到没有需要进位的位
class Solution {
public:
int Add(int num1, int num2) {
while(num2){
int t=(num1&num2)<<1;
num1=num1^num2;
num2=t;
}
return num1;
}
};
49 把字符串转换成整数
题目描述
将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0
示例1
输入:
"+2147483647"
返回值:
2147483647
思路:
设置一个标志位判断该整数时正数还是负数
循坏判断每一个字符是否在’0’到’9’之间,若不在范围内则不合法,若在范围内减去’0’就是int类型对应的数
class Solution {
public:
int StrToInt(string str) {
int flag=0;
if(str.size()==0)return 0;
if(str[0]=='-')flag=-1;
else if(str[0]=='+')flag=1;
int i,num=0;
if(flag==0){
i=0;
flag=1;
}
else i=1;
for(i;i<str.size();i++){
if(str[i]>'9'||str[i]<'0')return 0;
int t=str[i]-'0';
num=num*10+t;
}
return num*flag;
}
};
50 数组中重复的数字
题目描述
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中第一个重复的数字。 例如,如果输入长度为7的数组[2,3,1,0,2,5,3],那么对应的输出是第一个重复的数字2。没有重复的数字返回-1。
示例1
输入:
[2,3,1,0,2,5,3]
返回值:
2
思路:
利用位于算记录每个数出现的次数,遇上第一个重复出现的数之间返回结果
class Solution {
public:
int duplicate(vector<int>& numbers) {
int n=0;
for(int i=0;i<numbers.size();i++){
if(n&(1<<numbers[i]))return numbers[i];
n|=1<<numbers[i];
}
return -1;
}
};
51 构建乘积数组
题目描述
给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]A[1]…*A[i-1]A[i+1]…*A[n-1]。不能使用除法。(注意:规定B[0] = A[1] * A[2] * … * A[n-1],B[n-1] = A[0] * A[1] * … * A[n-2];)
对于A长度为1的情况,B无意义,故而无法构建,因此该情况不会存在。
示例1
输入:
[1,2,3,4,5]
返回值:
[120,60,40,30,24]
思路:
先计算下三角的积,B[n]=B[n-1]*A[n-1]
再计算上三角的积,temp*=A[n+1]
B[n]*=temp
class Solution {
public:
vector<int> multiply(const vector<int>& A) {
int length=A.size();
vector<int> B(length,1);
for(int i=1;i<length;i++){
B[i]=B[i-1]*A[i-1];
}
int temp=1;
for(int i=length-2;i>=0;i--){
temp*=A[i+1];
B[i]*=temp;
}
return B;
}
};
52 正则表达式匹配
题目描述
请实现一个函数用来匹配包括’.‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配
示例1
输入:
"aaa","a*a"
返回值:
true
思路:
利用动态规划的思想,dp[i] [j]表示s的前i个字符和p的前j个字符匹配,dp[i] [j]的取值分为以下几种情况
- s[i]==p[j]||p[j]==’.'意思时s和p当前字符匹配,此时dp[i] [j]=dp[i-1] [j-1]
- s和p当前字符不匹配但p[j]==’*'此时需要注意p[j-1]是否与s[i]匹配,若匹配dp[i] [j]=dp[i] [j-1]也可能是dp[i] [j]=dp[i] [j-2],若*匹配了多个字符,则可以看成划掉s当前字符,去s[i-1]去和p[j]匹配,即dp[i] [j]=dp[i-1] [j]
- 若p[j]==’*'且p[j-1]与s[i]不匹配,则dp[i] [j]=dp[i] [j-2]
- 若p[j]位字符,且与s[i]不匹配,dp[i] [j]==false
首先初始化s为空串的情况,再从s的首位开始匹配
class Solution {
public:
bool match(string str, string pattern) {
int len1=str.size(),len2=pattern.size();
vector<vector<bool>> dp(len1+1,vector<bool>(len2+1,false));
dp[0][0]=true;
for(int j=1;j<=len2;j++){
if(pattern[j-1]=='*')dp[0][j]=dp[0][j-2];
}
for(int i=1;i<=len1;i++){
for(int j=1;j<=len2;j++){
if(pattern[j-1]==str[i-1]||pattern[j-1]=='.'){
dp[i][j]=dp[i-1][j-1];
}
else if(pattern[j-1]=='*'){
if(pattern[j-2]==str[i-1]||pattern[j-2]=='.'){
dp[i][j]=dp[i][j-2]||dp[i][j-1]||dp[i-1][j];
}
else{
dp[i][j]=dp[i][j-2];
}
}
}
}
return dp[len1][len2];
}
};