基础知识
题目
1.Pow(x, n)( LeetCode 50 )
难度: 中等
题目表述:
实现 pow(x, n) ,即计算 x 的整数 n 次幂函数(即,xn )。
代码(C++):
class Solution {
public:
// 递归
double quickPow(double x, long long n) {
if (n == 0) return 1;
double y = quickPow(x, n / 2);
return n % 2 == 0 ? y * y : y * y * x;
}
// 迭代
double quickPow(double x, long long n) {
double ans = 1;
double new_x = x;
while (n > 0) {
if (n % 2 == 1) ans *= new_x;
new_x *= new_x;
n /= 2;
}
return ans;
}
double myPow(double x, int n) {
long long N = n;
return N >= 0 ? quickPow(x, N) : 1 / quickPow(x, -N);
}
};
题解:
借助整数的二进制拆分,就可以得到迭代计算的方法
⭐2.字符串相乘( LeetCode 43 )
难度: 中等
题目表述:
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
代码(C++):
class Solution {
public:
// 加法
string multiply(string num1, string num2) {
if (num1 == "0" || num2 == "0") return "0";
int m = num1.size(), n = num2.size();
string res = "0";
for (int i = n - 1; i >= 0; i--) {
string ans;
for (int j = n - 1; j > i; j--) {
ans.push_back(0);
}
int add = 0;
for (int j = m - 1; j >= 0; j--) {
int x = num1[j] - '0';
int y = num2[i] - '0';
int z = x * y + add;
ans.push_back(z % 10);
add = z / 10;
}
if (add != 0) {
ans.push_back(add);
}
reverse(ans.begin(), ans.end());
for (auto& c: ans) {
c += '0';
}
res = addString(ans, res);
}
return res;
}
string addString(string num1, string num2) {
int i = num1.size() - 1, j = num2.size() - 1, add = 0;
string ans;
while (i >= 0 || j >=0 || add != 0) {
int x = i >= 0 ? num1[i] - '0' : 0;
int y = j >= 0 ? num2[j] - '0' : 0;
int z = x + y + add;
ans.push_back(z % 10);
add = z / 10;
i--;
j--;
}
reverse(ans.begin(), ans.end());
for (auto& c: ans) {
c += '0';
}
return ans;
}
// 乘法
string multiply(string num1, string num2) {
if (num1 == "0" || num2 == "0") return "0";
int m = num1.size(), n = num2.size();
vector<int> ans(m + n, 0);
for (int i = m - 1; i >= 0; i--) {
int x = num1[i] - '0';
for (int j = n - 1; j >= 0; j--) {
int y = num2[j] - '0';
int z = x * y;
ans[i + j + 1] += z;
ans[i + j] += ans[i + j + 1] / 10;
ans[i + j + 1] %= 10;
}
}
string res;
for (int i = (ans[0] == 0 ? 1 : 0); i < m + n; i++) {
res += ans[i] + '0';
}
return res;
}
};
题解: 字符串相加 / 字符串相乘
字符串相加:模拟「竖式乘法」
字符串相乘:
num 1 和 num2 的乘积的长度为 m+n−1 或 m+n
num1[i] * num2[j] 的结果位于 ans[i+j+1],如果 ans[i+j+1]≥10,则将进位部分加到 ansArr[i+j]。
3.字符串转换整数 (atoi)( LeetCode 8 )
难度: 中等
题目表述:
请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。
代码(C++):
class Solution {
public:
int myAtoi(string s) {
int i = 0, sign = 1, ans = 0;
while (s[i] == ' ') {
i++;
}
if (s[i] == '-') sign = -1;
if (s[i] == '-' || s[i] == '+') {
i++;
}
while (i < s.size() && isdigit(s[i])) {
int r = s[i] - '0';
if (ans > INT_MAX / 10 || (ans == INT_MAX / 10 && r > 7)) {
return sign == 1 ? INT_MAX : INT_MIN;
}
ans = ans * 10 + r;
i++;
}
return sign * ans;
}
};
题解: 注意溢出截断
注意溢出截断时,为防止比较时溢出,可以在 x10 之前与被比较数 / 10 比较
4.整数反转( LeetCode 7 )
难度: 中等
题目表述:
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
代码(C++):
class Solution {
public:
int reverse(int x) {
int ans = 0;
while (x != 0) {
int y = x % 10;
if (ans > INT_MAX / 10 || ans < INT_MIN /10) return 0;
ans = ans * 10 + y;
x /= 10;
}
return ans;
}
};
题解:
即使ans和INT_MAX/10相等,也不可能出现个位数大于2的情况,因为原始数最大值的最高位是2。
小结
可以模拟加减乘除的数学思维解决问题。