1.大数加法
思路:
高精度板子,停留一下都是罪过!
代码:
class Solution {
public:
string solve(string s, string t) {
vector<int> a;
vector<int> b;
for(int i=s.size()-1;i>=0;i--)a.push_back(s[i]-'0');
for(int i=t.size()-1;i>=0;i--)b.push_back(t[i]-'0');
if(s.size()==0)a.push_back(0);
if(t.size()==0)b.push_back(0);
vector<int> c;
int tt=0;
for(int i=0;i<a.size()||i<b.size();i++){
if(i<a.size())tt+=a[i];
if(i<b.size())tt+=b[i];
c.push_back(tt%10);
tt/=10;
}
if(tt)c.push_back(tt);
string ans="";
for(int i=c.size()-1;i>=0;i--){
char u=c[i]+'0';
ans+=u;
}
return ans;
}
};
2.链表相加(二)
思路:
还是高精度,只不过数组换成了链表。但是换汤不换药,还是先反转一下,从低位开始加减。
在纸上画一下就好了。不过呢建议做链表题的时候多用哨兵节点,这样可以减少处理边界情况。还有就是链表题在传指针作为参数的时候,注意二级指针的问题。
代码:
#define _CRT_SECURE_NO_WARNINGS 1
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
class Solution {
public:
ListNode* relist(ListNode** head) {
ListNode* a = (*head)->next;
ListNode* pre = *head;
pre->next = nullptr;
if (a == nullptr)return *head;
while (a) {
//cout<<a->val<<endl;
ListNode* temp = a->next;
a->next = pre;
pre = a;
if (temp == nullptr)break;
a = temp;
}
// cout<<a->val<<endl;
return a;
}
ListNode* addInList(ListNode* head1, ListNode* head2) {
ListNode* a = relist(&head1);
ListNode* b = relist(&head2);
ListNode* c = (ListNode*)new ListNode(-1);
ListNode* p3 = c;
ListNode* p1 = a;
ListNode* p2 = b;
int t = 0;
while (p1 || p2) {
if (p1) {
t += p1->val;
p1 = p1->next;
}
if (p2) {
t += p2->val;
p2 = p2->next;
}
ListNode* temp = (ListNode*)new ListNode(t % 10);
p3->next = temp;
p3 = temp;
t /= 10;
}
if (t) {
ListNode* temp = (ListNode*)new ListNode(t % 10);
p3->next = temp;
p3 = temp;
t /= 10;
}
return relist(&c->next);
}
};
3.大数相乘
思路:
乘法高精度。比加法稍微多处理一些。两数相乘的结果最大的位数就是这两个数的位数和,比如10*100,最后的结果就是2+3=5位数。所以存答案的数组的空间开多大可以提前算出来。
模拟一下自己做乘法的过程,每次a的第i位乘以b的第j位,其结果一定在c的[i+j]位。
c此时[i+j]里有可能大于10,我们需要进位,进位就是c[i+j+1]=c[i+j]/10。进位之后再更新一下c[i+j]。
最后答案转为字符串。
值得注意的是,高精度乘法得到答案的最高位有可能不是一个一位数,比如2*10,此时的c[0]=10。这里我们用to_string就好了。
哦还有前导0的情况。为什么呢?因为我们存答案的数组c开的是理论上最大的空间,但是实际上可能不会用到这么多。比如一个一位数乘以一个一位数,最大得到一个二位数,我们就开2个int的空间。但是有可能是1*1=1还是一位数,多余的空间里存的0就是前导0.
代码:
#define _CRT_SECURE_NO_WARNINGS 1
class Solution {
public:
string solve(string s, string t) {
vector<int> a;
vector<int> b;
if (s == "0" || t == "0")return "0";
for (int i = s.size() - 1; i >= 0; i--)a.push_back(s[i] - '0');
for (int i = t.size() - 1; i >= 0; i--)b.push_back(t[i] - '0');
int n = a.size();
int m = b.size();
vector<int> c(m + n);
int tt = 0;
for (int i = 0; i < a.size(); i++) {
tt = 0;
for (int j = 0; j < b.size(); j++) {
tt = a[i] * b[j];
c[i + j] += tt;
// cout<<i*j<<"--"<<c[i*j]<<" ";
c[i + j + 1] += c[i + j] / 10;
c[i + j] %= 10;
}
}
int p = c.size() - 1;
while (c[p] == 0 && p >= 0) {
p--;
}
string ans = "";
for (int i = p; i >= 0; i--) {
string k = to_string(c[i]);
ans += k;
}
return ans;
}
};