題目
You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Example:
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.
解答
這題的長相就是很容易讓人想到鏈表數據結構的應用
然鵝,筆者好久沒有用C++寫結構體了,主要時間不是用來寫算法,而是用來創建鏈表hh~
解題思路:
數據輸入后,題干說是非空的鏈表,故不用判斷鏈表是否為空
這個方法有一點像高精度加法的感覺,最重要的是進位如何處理。
并且算法是對應位置元素相加,所以兩個指針最好同時移動,但是由于兩個鏈表長度可能相等,也可能不相等
需要注意這些情況
- 若鏈表1和鏈表2長度相等,則指向兩個鏈表的指針同時后移,到next
每次相加后都記下進位的變化,進位數累加到下一次相加操作。
若相加完成之后進位為0,就是可以直接出結果啦!
若是進位數為1,則結果鏈表還需要再新增一個鏈表node存下來,可不能丟了!
- 若鏈表1和鏈表2長度不相等,則指向兩個鏈表的指針同時后移,直到那個短的鏈表已經遍歷結束為止
此時指向短鏈表的指針已經到頭了,就不用往下遍歷了,但是指向長鏈表的指針還要和進位數相加,繼續遍歷,
直到長鏈表的指針也指向空,且進位數也妥善的被處理之后,循環結束。
判斷循環結束的條件
while(p!=NULL || q!=NULL || carry != 0)
筆者的輸入測試用例的格式是:
一行一個數
結束輸入使用q
如圖操作:
#include <iostream>
#include <cstdio>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
//不帶頭節點的尾插法
ListNode *createList()
{
ListNode *pHead = NULL;
ListNode *p = pHead;
char x;
while(cin>>x)
{
if(x == 'q')
{
break;
}
int value = x - '0';
ListNode *pNew = new ListNode(value);
pNew->next = NULL;
if(pHead == NULL)
{
pHead = pNew;
}
else
{
p->next = pNew;
}
p = pNew;
}
return pHead;
}
//循環打印鏈表
void displayList(ListNode *head)
{
ListNode *p = head;
while(p != NULL)
{
cout<<p->val<<"->";
p = p->next;
}
cout<<"NULL"<<endl;
}
//解題主體
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int carry = 0; //進位記錄
ListNode *p,*q;//指針p,q分別指向兩個鏈表
p = l1;
q = l2;
ListNode *result = NULL;
ListNode *pResult = result;
while(p!=NULL || q!=NULL || carry != 0) //結束循環的條件 很重要!?。? {
int add;
if (p != NULL && q != NULL)
{
add = p->val + q->val + carry;
p = p->next;
q = q->next;
}
else if (p == NULL && q != NULL)
{
add = 0 + q->val + carry;
q = q->next;
}
else if (p != NULL && q == NULL)
{
add = p->val + 0 + carry;
p = p->next;
}
else
{
add = 0 + 0 + carry;
}
int number = add % 10;
carry = add / 10;
ListNode *pNew = new ListNode(number);
pNew->next = NULL;
if(result == NULL)
{
result = pNew;
}
else
{
pResult->next = pNew;
}
pResult = pNew;
}
return result;
}
};
int main()
{
Solution s;
ListNode *l1,*l2,*result;
l1 = s.createList();
s.displayList(l1);
l2 = s.createList();
s.displayList(l2);
result = s.addTwoNumbers(l1,l2);
s.displayList(result);
return 0;
}