LeetCode -- AddTowNumbers

两个数相加。

题目:

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.

这个题目的算法其实就是,计算任意位数的整相加。注意,他这里是把数字倒过来了,465表示为5->6->4。

解决这道题目的核心是进位问题。

其次,还要考虑:

1、两个数字长度不同。例如:12344+1 = 12345。长度不同,实际上只有个位进行加法操作。

2、首尾数字不为0。例如:99+1 = 100。连续进位。

3、位数扩展。例如:8+7 = 15。加数都是1位,和却有2位。

代码1:比较朴素的代码,按照分析逻辑一步一步实现。

 public static ListNode Solution1(ListNode l1, ListNode l2)
        {
            int res = l1.val + l2.val; //当前节点相加的值
            ListNode listNode = new ListNode(res);
            ListNode headNode = listNode;
            ListNode p1 = l1.next; //指向l1
            ListNode p2 = l2.next; //指向l2

            //节点相加
            while (p1 != null || p2 != null)
            {
                listNode.next = new ListNode(
                    (p1 == null ? 0 : p1.val) + (p2 == null ? 0 : p2.val)
                    );
                listNode = listNode.next;
                p1 = p1 == null ? null : p1.next;
                p2 = p2 == null ? null : p2.next;
            }

            listNode = headNode;
            //进位处理
            while (listNode !=null)
            {
                if (listNode.val >= 10)
                {
                    if (listNode.next == null)
                    {
                        listNode.next = new ListNode(1);
                    }
                    else
                        listNode.next.val += 1;
                    listNode.val %= 10;
                }
                listNode = listNode.next;
            }
            return headNode;
        }

代码2:提高一下代码简洁性,像这种链表,很方便用递归去遍历,下面用递归去实现。

public static ListNode Solution2(ListNode l1, ListNode l2)
        {
            int sumNumber = (l1 == null ? 0 : l1.val) + (l2 == null ? 0 : l2.val);
            ListNode resList = new ListNode(sumNumber < 10 ? sumNumber : sumNumber % 10);
            if (l1.next == null && l2.next == null && sumNumber<10)
                return resList;
            else
            {
                if (l1.next == null) l1.next = new ListNode(sumNumber >= 10 ? 1 : 0);
                else if(sumNumber >= 10) l1.next.val += 1;
                if (l2.next == null) l2.next = new ListNode(0);
                resList.next = Solution2(l1.next,l2.next);
                return resList;
            }
        }

代码一下子简洁很多,但是速度反而没有代码1快,不能忍,优化一下。

代码3:优化递归代码。

public static ListNode Solution3(ListNode l1, ListNode l2)
        {
            int sumNumber = (l1 == null ? 0 : l1.val) + (l2 == null ? 0 : l2.val);
            bool sumBiggerThanTen = sumNumber >= 10;
            ListNode resList = new ListNode(sumBiggerThanTen ? sumNumber % 10 : sumNumber);
            if ((l1 == null || l1.next == null) && (l2 == null || l2.next == null) && !sumBiggerThanTen)
                return resList;
            else
            {
                if (sumBiggerThanTen && l1.next == null) l1.next = new ListNode(1);
                else if (sumBiggerThanTen) l1.next.val += 1;
                resList.next = Solution3(l1 == null ? null : l1.next, l2 == null ? null : l2.next);
                return resList;
            }
        }

速度明显变快,主要优化的点:

1、减少对象创建,尤其是new ListNode(0) ,在堆中分配对象很慢

 2、比较结果复用 sumBiggerThanTen = sumNumber >= 10;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值