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

 

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