LeetCode 445——两数相加 II
1. 题目

2. 解答
2.1 方法一
在 LeetCode 206——反转链表 和 LeetCode 2——两数相加 的基础上,先对两个链表进行反转,然后求出和后再进行反转即可。
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        // 先将两个链表反序
        l1 = reverseList(l1);
        l2 = reverseList(l2);
        ListNode *head = new ListNode(0); // 建立哨兵结点
        ListNode *temp = head; 
        int carry = 0; // 保留进位
        int sum = 0;
        while(l1 || l2)
        {
            if (l1 && l2) // 两个链表都非空
            {
                sum = l1->val + l2->val + carry;
                l1 = l1->next;
                l2 = l2->next;
            }
            else if (l1) // l2 链表为空,只对进位和 l1 元素求和
            {
                sum = l1->val + carry;
                l1 = l1->next;
            }
            else // l1 链表为空,只对进位和 l2 元素求和
            {
                sum = l2->val + carry;
                l2 = l2->next;
            } 
            // 求出和以及进位,将和添加到新链表中
            carry = sum >= 10 ? 1 : 0;
            sum = sum % 10;
            head->next = new ListNode(sum);
            head = head->next;
            if ( (l1 == NULL || l2 == NULL) && carry == 0 )
            {
                head->next = l1 ? l1 : l2;
                return reverseList(temp->next);
            }
        }
        if (carry) // 若最后一位还有进位,进位即为最后一位的和
        {
            head->next = new ListNode(carry);
        }
        head->next->next = NULL;
        return reverseList(temp->next);
    }
    ListNode* reverseList(ListNode* head) {
        if (head == NULL || head->next == NULL) return head;
        else
        {
            ListNode * p1 = head;
            ListNode * p2 = p1->next;
            ListNode * p3 = p2->next; 
            while (p2)
            {
                p3 = p2->next; p2->next = p1;
                p1 = p2;
                p2 = p3;
            }
            head->next = NULL;
            head = p1; 
            return head;
        }
    }
};
2.2 方法二
先求出两个链表的长度,然后对齐两个链表,按照对应位分别求出每一位的和以及进位,最后从最低位也就是最右边开始,将和与进位相加,新建节点在链表头部插入即可。
| 例 1 | ||||
|---|---|---|---|---|
| l1 | 7 | 2 | 4 | 3 | 
| l2 | 5 | 6 | 4 | |
| 和 | 7 | 7 | 0 | 7 | 
| 进位 | 0 | 1 | 0 | 0 | 
| 结果 | 7 | 8 | 0 | 7 | 
| 例 2 | ||||
|---|---|---|---|---|
| l1 | 9 | 9 | 9 | |
| l2 | 9 | 9 | ||
| 和 | 0 | 9 | 8 | 8 | 
| 进位 | 0 | 1 | 1 | 0 | 
| 结果 | 1 | 0 | 9 | 8 | 
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        int n1 = countListNodeNumber(l1);
        int n2 = countListNodeNumber(l2);
        ListNode* long_list = NULL;
        ListNode* short_list = NULL;
        int bigger_n = 0;
        int smaller_n = 0;
        if (n1 <= n2)
        {
            long_list = l2;
            short_list = l1;
            bigger_n = n2;
            smaller_n = n1;
        }
        else
        {
            long_list = l1;
            short_list = l2;
            bigger_n = n1;
            smaller_n = n2;
        }
        int temp = bigger_n - smaller_n + 1;
        int sum_array[bigger_n + 1] = {0};
        int carry_array[bigger_n + 1] = {0};
        int sum = 0;
        int carry = 0;
        ListNode* long_temp = long_list;
        ListNode* short_temp = short_list;
        for (unsigned int i = 1; i <= bigger_n; i++)
        {
            carry = 0;
            if (i < temp)
            {
                sum = long_temp->val;
            }
            else
            {
                sum = long_temp->val + short_temp->val;
                if (sum >= 10)
                {
                    sum = sum % 10;
                    carry = 1;
                }
                short_temp = short_temp->next;
            }
            sum_array[i] = sum;
            carry_array[i-1] = carry;
            long_temp = long_temp->next;
        }
        ListNode* new_head = new ListNode(0);
        long_temp = new_head;
        for (unsigned int i = bigger_n; i > 0; i--)
        {
            // 在链表头部进行插入
            sum = sum_array[i] + carry_array[i];
            if (sum >= 10)
            {
                sum = sum % 10;
                carry_array[i-1] = 1;
            }
            short_temp = new ListNode(sum);
            short_temp->next = long_temp->next;
            long_temp->next = short_temp;
        }
        sum = sum_array[0] + carry_array[0];
        if (sum)
        {
            short_temp = new ListNode(sum);
            short_temp->next = long_temp->next;
            long_temp->next = short_temp;
        }
        return new_head->next;
    }
    int countListNodeNumber(ListNode *head)
    {
        int node_num = 0;
        ListNode* slow = head;
        ListNode* fast = head; 
        while(fast && fast->next)
        {
            slow = slow->next;
            fast = fast->next->next;
            node_num++;
        } 
        if (fast)
        {
            node_num = node_num * 2 + 1;
        }
        else
        {
            node_num = node_num * 2;
        }
        return node_num;
    }
};
2.3 方法三
将两个链表的节点分别放入两个栈中,若两个栈都非空,拿两个栈顶元素和进位,求出和以及新的进位;若其中一个栈为空,则拿一个栈顶元素和进位,求出和以及新的进位。然后新建节点,在链表头部进行插入,最后只用处理一下最高位的进位即可。
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        stack<ListNode *> stack1;
        stack<ListNode *> stack2;
        while (l1)
        {
            stack1.push(l1);
            l1 = l1->next;
        }
        while (l2)
        {
            stack2.push(l2);
            l2 = l2->next;
        }
        int sum = 0;
        int carry = 0;
        ListNode *new_head = new ListNode(0);
        ListNode *temp = NULL;
        while (!stack1.empty() && !stack2.empty())
        {
            sum = stack1.top()->val + stack2.top()->val + carry;
            if (sum >= 10)
            {
                sum = sum % 10;
                carry = 1;
            }
            else
                carry = 0;
            temp = new ListNode(sum);
            temp->next = new_head->next;
            new_head->next = temp; 
            stack1.pop();
            stack2.pop();
        }
         while (!stack1.empty())
         {
            sum = stack1.top()->val + carry;
            if (sum >= 10)
            {
                sum = sum % 10;
                carry = 1;
            }
            else
                carry = 0;
            temp = new ListNode(sum);
            temp->next = new_head->next;
            new_head->next = temp; 
            stack1.pop();
         }
         while (!stack2.empty())
         {
            sum = stack2.top()->val + carry;
            if (sum >= 10)
            {
                sum = sum % 10;
                carry = 1;
            }
            else
                carry = 0;
            temp = new ListNode(sum);
            temp->next = new_head->next;
            new_head->next = temp; 
            stack2.pop();
         }
        if (carry)
        {
            temp = new ListNode(carry);
            temp->next = new_head->next;
            new_head->next = temp;
        }
        return new_head->next;
    }
};
获取更多精彩,请关注「seniusen」!

LeetCode 445——两数相加 II的更多相关文章
- LeetCode 445. 两数相加 II(Add Two Numbers II)
		445. 两数相加 II 445. Add Two Numbers II 题目描述 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个 ... 
- Java实现 LeetCode 445  两数相加 II
		445. 两数相加 II 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会 ... 
- Leetcode 445. 两数相加 II
		1.题目描述 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. ... 
- 力扣 - 445. 两数相加 II
		目录 题目 思路 代码实现 题目 给你两个 非空 链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储一位数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两 ... 
- 445. 两数相加 II
		Q: A: 这种题的用例是一定会搞一些很大的数的.long都会溢出,所以我们就不用尝试转数字做加法转链表的方法了.另外直接倒置两个链表再做加法的做法会改变原链表,题干也说了禁止改动原链表. 1.求两个 ... 
- Leetcode 002. 两数相加
		1.题目描述 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表 ... 
- LeetCode 2. 两数相加(Add Two Numbers)
		2. 两数相加 2. Add Two Numbers 题目描述 You are given two non-empty linked lists representing two non-negati ... 
- 445 Add Two Numbers II 两数相加 II
		给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表.你可以假设除了数字 0 之外,这两个数字都不会以零开头.进阶:如果输入链表 ... 
- [Swift]LeetCode445. 两数相加 II | Add Two Numbers II
		You are given two non-empty linked lists representing two non-negative integers. The most significan ... 
随机推荐
- Oracle中order by case 用法
			select * from ly_familyinformation ' ' order by case when relation = '购房人/申请人' then when relation = ... 
- Oracle作业5——多表查询、子查询
			一.基础练习: 1.查询和scott相同部门的员工姓名ename和雇用日期hiredate SELECT ENAME,HIREDATE FROM EMP WHERE DEPTNO=(SELECT DE ... 
- iOS:PrefixHeader / 头文件 / 宏定义(18-03-02更)
			宏定义,不一定放在PCH文件,可能放在一个.h文件,再用PCH包含进来. 1.屏幕尺寸 // 屏幕尺寸 #define kSCREEN_WIDTH [UIScreen mainScreen].boun ... 
- linux 安装 node 环境
			本篇学习的分享主要说在linux 安装 node 环境,个人也是在腾讯云的实验室课程学习的,这里只是个人的一个学习记录, 大家也可以去腾讯的实验室来体验一下,教程十分详细易学. 1 .安装 Node. ... 
- Jquery复选框的全选全不选及选择所有复选框实现全选的复选框
			Jquery代码 $(function () { $(":checkbox.parentfunc").click(function () { //如何获取被点击的那个复选框 $(t ... 
- md5加密+盐方式二
			这类md5+盐加密是属于自定义盐值的简单方法! 1.导入架包 2.调用方法 DigestUtils.md5Hex(password);//加密方法 举例 方式一: password=DigestUti ... 
- vue-知乎日志
			1.项目API来源 2.项目地址 3.截图 4.功能 首页 轮播图 动态消息 下拉刷新 动态 ... 
- HTML5文本
			1.重要文本.斜体文本 粗体:<strong></strong> 粗体:<b></b> 斜体:<em></em> 斜体:< ... 
- JAVA 中的文件读取
			1. InputStream / OutputStream处理字节流抽象类:所有输入.输出(内存)类的超类,一般使用 FileInputStream / FileOutputStream 输出字符 u ... 
- [STM32F4][关于看门狗的那些事]
			STM32(stm32f4XX系列)看门狗的总结: 1. 具有两个看门狗外设(独立和窗口)均可用于检测并解决由软件错误导致的故障:当计数器达到给定的超时值时,触发一个中断(仅适用于窗口看门狗)或产生一 ... 
