一、第一种方法(失败):
1、简单以为将两个链表的val转换成数值比如3->4->5转换成543,7->8->9转换成987,然后相加即:543+987 = 1503,最后再转换回来输出 3->0->5->1即可
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
//将第一个链表存入栈中
ListNode* temp = l1;
stack<int> l1_stack, l2_stack;
while (temp != nullptr){
l1_stack.push(temp->val);
temp = temp->next;
}
//将第二个链表存入栈中
temp = l2;
while (temp != nullptr){
l2_stack.push(temp->val);
temp = temp->next;
}
int size = l1_stack.size() - 1;
long long l1_num = 0, l2_num = 0, res_num = 0;
//将第一个链表栈中的数字变成加起来
while (!l1_stack.empty()){
int test1 = l1_stack.top();
l1_stack.pop();
l1_num += test1 *pow(10, size--);
}
//将第二个链表栈中的数字变成加起来
size = l2_stack.size() - 1;
while (!l2_stack.empty()){
int test1 = l2_stack.top();
l2_stack.pop();
l2_num += test1*pow(10, size--);
}
//q求和
res_num = l1_num + l2_num;
//将求和的结果拆分存放到队列中
queue<int> res_queue;
long long yushu, res = res_num;
ListNode* head = NULL, *cur = NULL;
if (res == 0){
head = new ListNode(res);
return head;
}
while (res>0){
yushu = res % 10;//获取余数
res /= 10;//获取除数
res_queue.push(yushu);//队列中存入余数
}
//遍历队列创建新链表返回
head = new ListNode(res_queue.front());//因为非空链表,这个肯定中
cur = head;
res_queue.pop();
while (!res_queue.empty()){
cur->next = new ListNode(res_queue.front());
cur = cur->next;
res_queue.pop();
}
return head;
}
};
结果...报错说int不够大,好呀,我修改代码为将l1_num和l2_num修改为long long类型
然后还是有几个通不过....long long类型还是通不过...
难道要我转换成字符串再处理,好的吧,太复杂了,换个思路吧
二、第二种方法(不满意)
2、可以发现直接从左到右相加并考虑进位就是最后的答案。这里需要考虑最后一个进位,如果存在别忘记添加。
然后我只会使用if-else解决问题...并且思路还贼乱....
乱也是自己挖的坑,想着遍历这两个链表再相加好了,但是如何确定遍历顺序?循环结束条件是那个,我第一反应总是选择循环结束条件为长的那个链表,来吧:
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int size1 = 0, size2 = 0;
ListNode* cur1 = l1, *cur2 = l2;
while (cur1){//统计链表1结点个数
++size1;
cur1 = cur1->next;
}
while (cur2){//统计链表2结点个数
++size2;
cur2 = cur2->next;
}
//返回最大的链表结点个数
int size = size1>size2 ? size1 : size2;
vector<int> res;
cur1 = l1, cur2 = l2;
bool flag = 1; //某个链表遍历结束标志位
int carry = 0; //进位
for (int i = 0; i<size; ++i){
int add_res = 0;
if (i == min(size1, size2)){
flag = 0;//判断某个链表是否到尽头
}
if (flag == 1){//没到尽头,相加,同时走
int add_res = cur1->val + cur2->val + carry;
if (add_res >= 10){ //如果大于10则进位
add_res = add_res - 10;
carry = 1;
}
else carry = 0;
res.push_back(add_res);
cur1 = cur1->next;
cur2 = cur2->next;
}
else{//到某个链表的尽头了
if (size == size1){//链表2结束
add_res = cur1->val;
cur1 = cur1->next;
}
else{//链表1结束
add_res = cur2->val;
cur2 = cur2->next;
}
//添加进位
if (carry == 1){
add_res += carry;
carry = 0;
}//处理进位
if (add_res >= 10){
add_res = add_res - 10;
carry = 1;
}
res.push_back(add_res);
}
}
if (carry == 1){//最后一位
res.push_back(1);
}
ListNode* head = new ListNode(res[0]);
ListNode* cur = head;
for (int j = 1; j<res.size(); ++j){
cur->next = new ListNode(res[j]);
cur = cur->next;
}
return head;
}
};
结束条件写的长的那个链表,就需要使用flage作为标志,判断短链表是否结束,其实短链表已经结束了还总是往循环里面跑,只是flage控制了它不再对短链表进行操作而言。 可以改进为循环结束时短的链表。
三、第二种方法的改进(还凑合)
循环结束条件为短链表遍历结束。这里的处理思路就和归并排序的merge过程有点像了,需要同时遍历两个都长短不一的数组/链表时,一般以短数组/链表的长度作为遍历结束条件,然后长数组/链表继续以短的结尾继续向前操作,上面那个方法看起来十分复杂就是因为遍历的结束条件是长链表。
修改以后这个代码看起来就...也还可以...反正就是过了
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int size1 = 0, size2 = 0;
ListNode* cur1 = l1, *cur2 = l2;
while (cur1){//统计链表1结点个数
++size1;
cur1 = cur1->next;
}
while (cur2){//统计链表2结点个数
++size2;
cur2 = cur2->next;
}
//返回最短的链表结点个数
int size = size1<size2 ? size1 : size2;
vector<int> res;
cur1 = l1, cur2 = l2;
int carry = 0; //进位
int add_res = 0;
for (int i = 0; i < size; ++i){//遍历短链表,cur1和cur2同时前进
add_res = cur1->val + cur2->val + carry;
if (add_res >= 10){ //处理进位
add_res -= 10;
carry = 1;
}
else carry = 0;//否则,进位恢复为0
cur1 = cur1->next;
cur2 = cur2->next;
res.push_back(add_res);
}
if (size == size1){//表示size2没有遍历完成
for (int i = size; i < size2; ++i){
add_res = cur2->val + carry;
if (add_res >= 10){ //处理进位
add_res -= 10;
carry = 1;
}
else carry = 0;
cur2 = cur2->next;
res.push_back(add_res);
}
}
else{//表示size1没有遍历完成
for (int i = size; i < size1; ++i){
add_res = cur1->val + carry;
if (add_res >= 10){ //处理进位
add_res -= 10;
carry = 1;
}
else carry = 0;
cur1 = cur1->next;
res.push_back(add_res);
}
}
if (carry == 1){//最后一位进位
res.push_back(1);
}
ListNode* head = new ListNode(res[0]);
ListNode* cur = head;
for (int j = 1; j<res.size(); ++j){
cur->next = new ListNode(res[j]);
cur = cur->next;
}
return head;
}
};
追求更简洁点,如下:
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int size1 = 0, size2 = 0;
ListNode* cur1 = l1, *cur2 = l2;
while (cur1){//统计链表1结点个数
++size1;
cur1 = cur1->next;
}
while (cur2){//统计链表2结点个数
++size2;
cur2 = cur2->next;
}
//返回最短的链表结点个数
int size = size1<size2 ? size1 : size2;
vector<int> res;
cur1 = l1, cur2 = l2;
int carry = 0; //进位
int add_res = 0;
int index = 0;
for (; index < size; ++index){//遍历短链表,cur1和cur2同时前进
add_res = cur1->val + cur2->val + carry;
if (add_res >= 10){ //处理进位
add_res -= 10;
carry = 1;
}
else carry = 0;//否则,进位恢复为0
cur1 = cur1->next;
cur2 = cur2->next;
res.push_back(add_res);
}
while (index<size1){//说明size2结束了
add_res = cur1->val + carry;
if (add_res >= 10){ //处理进位
add_res -= 10;
carry = 1;
}
else carry = 0;
cur1 = cur1->next;
res.push_back(add_res);
index += 1;
}
while (index < size2){//说明size1结束了
add_res = cur2->val + carry;
if (add_res >= 10){ //处理进位
add_res -= 10;
carry = 1;
}
else carry = 0;
cur2 = cur2->next;
res.push_back(add_res);
index += 1;
}
if (carry == 1){//最后一位进位
res.push_back(1);
}
ListNode* head = new ListNode(res[0]);
ListNode* cur = head;
for (int j = 1; j<res.size(); ++j){
cur->next = new ListNode(res[j]);
cur = cur->next;
}
return head;
}
};