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;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章