1. 程式人生 > >面試12之給定兩個連結串列ListNode* A,ListNode* B,請返回A+B的結果

面試12之給定兩個連結串列ListNode* A,ListNode* B,請返回A+B的結果


有兩個用連結串列表示的整數,每個結點包含一個數位。這些數位是反向存放的,也就是個位排在連結串列的首部。編寫函式對這兩個整數求和,並用連結串列形式返回結果。
給定兩個連結串列ListNode* A,ListNode* B,請返回A+B的結果(ListNode*)。
測試樣例:
{1,2,3},{3,2,1}

返回:{4,4,4}

本題的思路很簡單,按照小學數學中學習的加法原理從末尾到首位,對每一位對齊相加即可。技巧在於如何處理不同長度的數字,以及進位和最高位的判斷。這裡對於不同長度的數字,我們通過將較短的數字補0來保證每一位都能相加。尤其是別忘了最高位有可能有進位。

#include<iostream>
using namespace std;

struct ListNode
{
	int val;
	struct ListNode *next;
	ListNode(int x):val(x),next(NULL)
	{

	}
};

ListNode* PlusAB(ListNode *a, ListNode*b)
{
	if(a == NULL)
		return b;
	if(b == NULL)
		return a;

	ListNode *pa = a;
	ListNode *pb = b;
	int step = 0;
	int sum = 0;
	ListNode *newHead = NULL;
	ListNode *pCur = newHead;
	
	while (pa != NULL ||pb != NULL)
	{
		
		int Aval = (pa == NULL ? 0 :pa->val);//注意當兩個連結串列不一樣長的時候,有一個連結串列肯定要先走到末尾,不能一直用pa->val或pb->val
		int Bval = (pb == NULL ? 0 :pb->val);
		sum = Aval + Bval+step;

		ListNode *pm = new ListNode(sum%10);

		if(newHead == NULL) //新連結串列的第一個節點
		{
			newHead = pm;
			pCur = newHead;
		}
		else
		{
			pCur->next = pm;
			pCur = pm;
		}
		
		step = sum / 10;

		pa = (pa != NULL ? pa->next :NULL);
		pb = (pb != NULL ? pb->next :NULL);
	}
	if(step != 0) //最高位有可能有進位。
	{
		
		ListNode *pm = new ListNode(step);
		pCur->next = pm;
	}
	return newHead;
}

void test()
{
	ListNode *p1 = new ListNode(6);
	ListNode *p2 = new ListNode(5);
	ListNode *p3 = new ListNode(4);
	p1->next = p2;
	p2->next = p3;
	
	ListNode *p4 = new ListNode(3);
	ListNode *p5 = new ListNode(2);
	ListNode *p6 = new ListNode(1);
	p4->next = p5;
	p5->next = p6;

	ListNode *phead = PlusAB(p1,p4);

	while(phead)
	{
		cout << phead->val << " ";
		phead = phead->next;
	}
}

int main()
{
	test();
	cout << "hello..." <<endl;
	return 0;
}