目录
题目
描述
假定用链表表示两个数,其中每个节点仅包含一个数字。假设这两个数的数字顺序
排列,请设计一种方法将两个数相加,并将其结果表现为链表的形式。
样例
样例 1:
输入: 6->1->7 2->9->5
输出: 9->1->2
样例 2:
输入: 1->2->3 4->5->6
输出: 5->7->9
解析
最开始我的想法是将两个链表转化为数字,然后相加,最后再将相加的那个值转化为字符串,但是当链表过长时,会导致溢出,链表转化出来的数字超过了int和longlong的范围。不能过所有的样例。
/**
* Definition of singly-linked-list:
* class ListNode {
* public:
* int val;
* ListNode *next;
* ListNode(int val) {
* this->val = val;
* this->next = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param l1: The first list.
* @param l2: The second list.
* @return: the sum list of l1 and l2.
*/
ListNode* addLists2(ListNode *l1, ListNode *l2) {
long long num1 = 0,num2 = 0;
while(l1) {
num1 = num1 * 10 + l1 -> val;
l1 = l1 -> next;
}
while(l2) {
num2 = num2 * 10 + l2 -> val;
l2 = l2 -> next;
}
//先计算出l1和l2的大小
long long num3 = num1 + num2;
//l3的大小,再将它转化为一条链表即可
string l3s = to_string(num3);
ListNode* p = new ListNode(0);
ListNode* head = p;
for (char c : l3s) {
p->next = new ListNode(c - '0');
p = p->next;
}
return head->next;
// write your code here
}
};
然后进行了更改,不将链表转化为数字,而是转化为字符串然后再进行大数相加,再将最后得到的字符串转化为链表即可。 这样可以避免转化为整数而导致的溢出错误。
-
链表转字符串:
-
直接遍历链表,将每个节点的值拼成字符串,保留原始高位顺序(例如
2->8->2
转为"282"
)。
-
-
字符串大数相加:
-
从最低位(字符串末尾)开始逐位相加,处理进位。
-
结果需要反转,因为加法是从低位到高位计算的。
-
-
字符串转链表:
-
按照字符串顺序直接创建链表,保持高位在前。
-
-
时间复杂度:O(max(m,n)),其中 m 和 n 是链表长度。
代码
/**
* Definition of singly-linked-list:
* class ListNode {
* public:
* int val;
* ListNode *next;
* ListNode(int val) {
* this->val = val;
* this->next = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param l1: The first list.
* @param l2: The second list.
* @return: the sum list of l1 and l2.
*/
// 将链表转为字符串(高位在前)
string listToString(ListNode* head) {
string s;
while (head) {
s += to_string(head->val);
head = head->next;
}
return s;
}
// 大数相加(字符串处理)
string addStrings(string num1, string num2) {
int i = num1.size()-1, j = num2.size()-1;
int carry = 0;
string res;
while (i >= 0 || j >= 0 || carry > 0) {
int n1 = (i >= 0) ? (num1[i--] - '0') : 0;
int n2 = (j >= 0) ? (num2[j--] - '0') : 0;
int sum = n1 + n2 + carry;
res.push_back(sum % 10 + '0');
carry = sum / 10;
}
reverse(res.begin(), res.end()); // 结果需要反转
return res;
}
// 将字符串转为链表(高位在前)
ListNode* stringToList(const string& s) {
ListNode* dummy = new ListNode(0);
ListNode* curr = dummy;
for (char c : s) {
curr->next = new ListNode(c - '0');
curr = curr->next;
}
return dummy->next;
}
ListNode* addLists2(ListNode *l1, ListNode *l2) {
string s1 = listToString(l1);
string s2 = listToString(l2);
string sum = addStrings(s1, s2);
return stringToList(sum);
// write your code here
}
};