47 求1+2+3…+n

题目描述

求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

示例1

输入:

1
5

返回值:

1
15

思路:

题目限制不能使用乘除法和条件判断语句,所以只能使用递归来计算

1
2
3
4
5
6
7
class Solution {
public:
int Sum_Solution(int n) {
if(n==1)return n;
return n+Sum_Solution(n-1);
}
};

48 不用加减乘除做加法

题目描述

写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

示例1

输入:

1
1,2

返回值:

1
3

思路:

不能用四则运算符号,所以要使用位运算。

两个整数&运算,等于1的位需要向前进一位,两个整数^运算,等于1的是不需要进位的位

把进位后的数和不需要进位的数再次&运算,循环执行直到没有需要进位的位

1
2
3
4
5
6
7
8
9
10
11
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

输入:

1
"+2147483647"

返回值:

1
2147483647

思路:

设置一个标志位判断该整数时正数还是负数

循坏判断每一个字符是否在’0’到’9’之间,若不在范围内则不合法,若在范围内减去’0’就是int类型对应的数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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

输入:

1
[2,3,1,0,2,5,3]

返回值:

1
2

思路:

利用位于算记录每个数出现的次数,遇上第一个重复出现的数之间返回结果

1
2
3
4
5
6
7
8
9
10
11
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
[1,2,3,4,5]

返回值:

1
[120,60,40,30,24]

思路:

img

先计算下三角的积,B[n]=B[n-1]*A[n-1]

再计算上三角的积,temp*=A[n+1]

B[n]*=temp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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

输入:

1
"aaa","a*a"

返回值:

1
true

思路:

利用动态规划的思想,dp[i] [j]表示s的前i个字符和p的前j个字符匹配,dp[i] [j]的取值分为以下几种情况

  1. s[i]==p[j]||p[j]==’.’意思时s和p当前字符匹配,此时dp[i] [j]=dp[i-1] [j-1]
  2. 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]
  3. 若p[j]==’*‘且p[j-1]与s[i]不匹配,则dp[i] [j]=dp[i] [j-2]
  4. 若p[j]位字符,且与s[i]不匹配,dp[i] [j]==false

首先初始化s为空串的情况,再从s的首位开始匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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];
}
};