單鏈表-兩數相加

題目來源LeetCode第445題

一、思路

給定兩個非空鏈表來代表兩個非負整數。數字最高位位於鏈表開始位置。它們的每個節點只存儲單個數字。將這兩數相加會返回一個新的鏈表。舉例:

輸入: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出: 7 -> 8 -> 0 -> 7

抽象至邏輯結構的層面,實際上就是豎式加法。從低位向高位進行計算,額外的進位也需要加上。麻煩就麻煩在,存儲結構是鏈表,只進行順序存取(無法倒退),也即不能直接使用兩根指針分別遍歷到最低位然後倒退着相加了。可以用幫助我們完成倒退,也可以使用連續的數據結構例如字符串(性質是隨機存取,靈活性高於順序存取)完成倒退的動作。

1.1 知識點

棧的性質,後進先出。本條性質本身就有逆序(反轉、倒退,表述是同一個意思)的效果。

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
	if (!l1 || !l2) return !l1 ? l2 : l1; //處理兩鏈表存在空表的情況
	stack<int> stk1, stk2;
	while (l1) {
		stk1.push(l1->val);
		l1 = l1->next;
	}//表1入棧
	while (l2) {
		stk2.push(l2->val);
		l2 = l2->next;
	}//表2入棧
	ListNode *dummy = new ListNode(0); //創建啞結點,統一新表的結點插入
	ListNode *current = NULL; //指向新創建的結點
	int carry = 0, n1, n2, sum; //標記進位、鏈表1和2的1位數字、1位數之和

	while (!stk1.empty() || !stk2.empty() || carry) {
		if (stk1.empty()) n1 = 0;
		else { n1 = stk1.top(); stk1.pop(); } //從表1取出1位
		if (stk2.empty()) n2 = 0;
		else { n2 = stk2.top(); stk2.pop(); } //從表2取出1位

		sum = n1 + n2 + carry; //記錄本輪1位數之和
		carry = sum / 10; //記錄本輪進位

		//尾插法建立新的鏈表(逆序)
		current = new ListNode(sum % 10);
		current->next = dummy->next;
		dummy->next = current;
	} //存在非空的棧,或者存在進位循環繼續進行
	ListNode *retNode = dummy->next;
	delete dummy;
	return retNode;
}

1.2 知識點

字符串具有極好的性質——隨機存取。也即我們可以在字符串中進行相關計算,最後在創建新表的時候,寫入數據。

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
	string str1, str2; //依次寫入字符串中
	while (l1) { str1 += to_string(l1->val); l1 = l1->next; }
	while (l2) { str2 += to_string(l2->val); l2 = l2->next; }

	//加法
	string ans;
	int carry = 0, i = str1.size() - 1, j = str2.size() - 1;
	while (i >= 0 || j >= 0 || carry) {
		if (i >= 0) carry += str1[i--] - '0';
		if (j >= 0) carry += str2[j--] - '0';
		ans = to_string(carry % 10) + ans;
		carry /= 10;
	}
	//頭插法建立新鏈表
	ListNode *dummy = new ListNode(0);
	ListNode *prev = dummy;
	for (auto i : ans) {
		ListNode *current = new ListNode(i - '0');
		prev->next = current;
		prev = current;
	}
	ListNode *retNode = dummy->next;
	delete dummy; //釋放啞結點
	return retNode;
}

 

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