您的位置:首页 > 其它

leetcode 2 Add Two Numbers

2015-08-09 10:37 513 查看
leetcode的第二题比较简单,题目如下:

Add Two Numbers

Total Accepted: 78845 Total Submissions: 385095

You are given two linked lists representing two non-negative numbers. >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.

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)

Output: 7 -> 0 -> 8

这道题其实就是手动完成两个数的加法运算, 我们要做的其实就是两个数的对应位相加, 如果之前有进位的话, 在把和与进位相加. 如果相加的结果需要进位的话, 那么我们保存进位, 待下两个数相加时再使用.

struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
struct ListNode* num1 = l1;
struct ListNode* num2 = l2;

int carry = 0;
struct ListNode *pTemp, *pPrevious, *result;

pPrevious = NULL;


首先把l1和l2存到num1和num2中,这样做不是必须,主要是我想保留这两个指向链表头的指针。carry表示是进位,初始化为0。接着的三个指针,pTemp指向链表中的当前节点,pPrevious指向链表中的上一个节点。result指向最后将会返回的保存两数合的链表。由于刚开始时,不存在先前节点,所以pPrevious指向NULL。

while(num1 != NULL || num2 != NULL || carry != 0)
{
if(num1 == NULL)
{
num1 = (struct ListNode*)malloc(sizeof(struct ListNode));
num1->val = 0;
num1->next = NULL;
}

if(num2 == NULL)
{
num2 = (struct ListNode*)malloc(sizeof(struct ListNode));
num2->val = 0;
num2->next = NULL;
}


链表中的每位对应数字相加就是通过这样一个while循环来实现的。我们判断计算完成的条件是指向第一个链表的指针指向NULL,指向第二个链表的指针指向NULL,表示两个数的所有位都加完了,同时进位为0。设置这样条件是因为两数相加会出现的两大类情况,第一类是最高位没出现进位,这又可以细分为两种情况,第一种是两个数的位数相同,例如:320+100= 400,另一种是两个数的位数不同,例如:320+1000= 1300;第二类是最高位出现进位,同样可以细分为两种情况,第一种是两个数的位数相同,例如:320+800=1120,另一种是两个数的位数不同,例如:320+9800=10120。后面的代码目的就是把两个数的位数补成相同,仿佛是在最高位补0,例如:320+1000就变成了0320+1000。值得一提的是两个数有可能同时在最高位补0,例如:320+9800当我们补成0320+9800后发现,最高位0和9相加后,还有一个进位需要处理。所以while循环还需要在执行一次,补成00320+09800,然后再最高位上加上进位1。

int sum = num1->val + num2->val + carry;
if(sum >= 10)
carry = 1;
else
carry = 0;
num1 = num1->next;
num2 = num2->next;


因为我们是一位一位地计算,所以这个地方的sum表示的该位的计算结果,例如:540+722,个位的sum是2,十位的sum是6,百位的sum是12。而如果大于等于10,那么就要进位。当一位计算完了之后,指针移向下一位。

pTemp = (struct ListNode*)malloc(sizeof(struct ListNode));
pTemp->val = sum % 10;
pTemp->next = NULL;
if(pPrevious != NULL)
{
pPrevious->next = pTemp;
}
else
{
result = pTemp;
}
pPrevious = pTemp;
}
return result;
}


由于每个数都是由链表保存的,所以我们需要把结果存入到result所指向的链表中。我们先分配一个新节点,然后把当前位的计算结果存入到节点中,由于最新的节点所以还没有后继节点,因此next指针赋值为NULL。下面的判断语句用于确定当前节点是不是链表中第一个节点,如果不是,那么存在前驱节点,就把前驱节点的next指针指向当前节点。如果是,那么result指针指向当前节点,因为它是链表的头节点。当这些操作完成后,我们准备开始计算下一位,因此pPrevious指向当前节点,因为当前节点是下一节点(即下一位)的前驱节点。当所有计算都执行完后,返回指向存放最终结果链表的result指针。

下面是全部代码:

#include <iostream>
#include "stdlib.h"
using namespace std;

struct ListNode
{
int val;
struct ListNode *next;
};

struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2)
{
struct ListNode* num1 = l1;
struct ListNode* num2 = l2;

int carry = 0;
struct ListNode *pTemp, *pPrevious, *result;

pPrevious = NULL;
while(num1 != NULL || num2 != NULL || carry != 0) { if(num1 == NULL) { num1 = (struct ListNode*)malloc(sizeof(struct ListNode)); num1->val = 0; num1->next = NULL; } if(num2 == NULL) { num2 = (struct ListNode*)malloc(sizeof(struct ListNode)); num2->val = 0; num2->next = NULL; }
int sum = num1->val + num2->val + carry; if(sum >= 10) carry = 1; else carry = 0; num1 = num1->next; num2 = num2->next;

pTemp = (struct ListNode*)malloc(sizeof(struct ListNode));
pTemp->val = sum % 10;
pTemp->next = NULL;
if(pPrevious != NULL)
{
pPrevious->next = pTemp;
}
else
{
result = pTemp;
}
pPrevious = pTemp;
}
return result;
}

int main()
{
cout<<"How many digits does first number have?"<<endl;
int size1, size2, tmp;
struct ListNode *pTemp, *pPrevious, *num1, *num2;
cin>>size1;

cout<<"Input digits with " " between each other:"<<endl;

pPrevious = NULL;

for(int i = 0; i < size1; i++)
{
cin>>tmp;
pTemp = (struct ListNode*)malloc(sizeof(struct ListNode));
pTemp->val = tmp;
pTemp->next = NULL;

if(pPrevious != NULL)
{
pPrevious->next = pTemp;
}
else //ys pTemp points to the first element
{
num1 = pTemp;
}
pPrevious = pTemp;
}

cout<<"How many digits does second number have?"<<endl;
cin>>size2;

cout<<"Input digits with " " between each other:"<<endl;

pPrevious = NULL;

for(int i = 0; i < size2; i++)
{
cin >> tmp;

pTemp = (struct ListNode*)malloc(sizeof(struct ListNode));
pTemp->val = tmp;
pTemp->next = NULL;

if(pPrevious != NULL)
{
pPrevious->next = pTemp;
}
else
{
num2 = pTemp;
}

pPrevious = pTemp;

}

struct ListNode *result = addTwoNumbers(num1, num2);

while(result != NULL)
{
cout<<result->val<<" ";
result = result->next;
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode