题目:
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
题意:
首先题意理解,输入为两个单链表,每一个链表的元素均为0~9的数字,而每一个链表示一个数字,头部是最低位,尾部是最高位。例如上述题目中Input的两个链表分别表示342 以及 465.
那么问题就来了,输出为新的链表,该链表以同样的方式表示输入的两个数字之和。
Key Point:
记录进位
坑:
可以写两个方法,将链表内容转换成数字,以及将数字转换成对应的链表。于是就有了以下步骤:
- list1, list2 <convertListToNum> num1, num2;
- value = num1 + num2;
- value <convertNumToList> newList;
如果题目中规定了链表的长度,这种方法未尝不可,可是没有~ 计算机中无论int(最大表示到2^4),long(最大也表示到2^4),long long(最大表示到2^8)等都有极限,而链表理论上可以形成很大的数字,很容易就能够突破 , 所以使用数值类型来存储结果是不可能通过所有case的。因此可以使用非数值型来存储,但是无形中增加了该题目的复杂度。
解答:
既然题目给的链表结果就是从低位向高位(很舒服,如果逆向又得费点事),逐次针对链表两个元素进行相加,记录每一次的进位,注意 题目并没有说输入的两个链表长度一致。以下是代码实现,通过leetCode的OJ
1 class Solution { 2 public: 3 // 记录每一次的进位,这样就突破了数值型的限制 4 ListNode *addTwoNumbers2(ListNode *l1, ListNode *l2){ 5 ListNode *root = NULL, *pre = NULL; 6 int nCarry = 0; // 每一个数位能够产生的进位最多为1,所以可以采用bool或者1bit表示 7 8 while (NULL != l1 || NULL != l2){ 9 int nodeVal = 0; 10 if (NULL == l1){ 11 nodeVal = l2->val + nCarry; 12 l2 = l2->next; 13 } 14 else if (NULL == l2){ 15 nodeVal = l1->val + nCarry; 16 l1 = l1->next; 17 } 18 else{ 19 nodeVal = l1->val + l2->val + nCarry; 20 l1 = l1->next; 21 l2 = l2->next; 22 } 23 24 if (nodeVal >= 10){ // 产生进位 25 nCarry = 1; 26 nodeVal %= 10; 27 } 28 else{ 29 nCarry = 0; // 进位清零 30 } 31 32 ListNode *node = new ListNode(nodeVal); 33 if (pre == NULL){ 34 root = node; 35 } 36 else{ 37 pre->next = node; 38 } 39 pre = node; // 记录上次节点,串联整个链表使用 40 }// while 41 42 if (nCarry != 0){ // 当链表结束如果还有进位,需要增加一个最高位节点 43 ListNode * lastNode = new ListNode(nCarry); 44 45 if (NULL != pre){ 46 pre->next = lastNode; 47 } 48 }// nCarry != 0 49 50 return root; 51 } 52 }
运行结果:
如果有什么问题,希望各位不吝赐教,小弟感恩答谢!