力扣2--两数相加详解

一、第一种方法(失败): 

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;
	}
};

 

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章