1.字符串相乘
给定两个以字符串形式表示的非负数num1和num2,返回num1和num2的乘积,它们的乘积也表示为字符串形式。
思路:
- 数字相乘的规律
假设num1的长度为m,num2的长度为n,那么它们乘积的长度一定不超过m+n。
所以创建一个字符数组value保存结果,长度为m+n - 乘法计算
循环遍历两个字符串,将num1[i]和num2[j]相乘,并可以将结果存入到value[i + j + i]中。
- 处理进位
从低位开始,一次将value数组中每一位对10求余,并对10求商作为进位。 - 处理最前端的0
之前设置的数组长度为m+n,结果可能会小于这个长度,需要将前面的0全部清楚掉。但要至少保留一位数。
string multiply(string num1, string num2) {
string res;
vector<int> value(num1.length() + num2.size(), 0);
for(int i = 0; i < num1.length(); i++)
{
for(int j = 0; j < num2.length(); j++)
{
value[i + j + 1] += (num1[i] - '0') * (num2[j] - '0');
}
}
//处理进位
int carry = 0;
for(int i = value.size() - 1; i >= 0; i--)
{
value[i] += carry;
carry = value[i] / 10;
value[i] %= 10;
}
//处理前端的0
int beginIndex = 0;
while(beginIndex < value.size() - 1 && value[beginIndex] == 0)
{
beginIndex++;
}
for(int i = beginIndex; i < value.size(); i++)
{
res += to_string(value[i]);
}
return res;
}
2.全排列
给定一个没有重复数字的序列,返回其所有可能的全排列。
思路:利用回溯法,与组合数思路相同
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> res;
vector<int> temp;
vector<int> flag(nums.size(), 0);
traceback(nums, temp, res, flag);
return res;
}
void traceback(vector<int>& nums, vector<int>& temp, vector<vector<int>>& res, vector<int>& flag)
{
if(temp.size() == nums.size())
{
res.push_back(temp);
return;
}
for(int i = 0 ; i < nums.size(); i++)
{
if(flag[i] == 0)
{
temp.push_back(nums[i]);
flag[i] = 1;
traceback(nums, temp, res, flag);
flag[i] = 0;
temp.pop_back();
}
}
}