• LeetCode 445 两数相加 II


    链接:https://leetcode-cn.com/problems/add-two-numbers-ii

    给定两个非空链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储单个数字。将这两数相加会返回一个新的链表。

    你可以假设除了数字 0 之外,这两个数字都不会以零开头。

    进阶:

    如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转。

    示例:

    输入: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
    输出: 7 -> 8 -> 0 -> 7

    这道题呢,也有两种解法,一种是用栈来做,另一种是用递归来做。栈解法比较简单直观,所以先来看看用栈怎么做的吧~

    首先,我们把这两个链表分别用两个栈存储,那么因为栈是先进后出的结构嘛,所以呢,每次取栈的top元素,相当于就是取链表的尾结点啦。得到两个尾结点,那当然就要把它们求和咯。到这里,就像前一道倒序链表求和题了。。进位的处理啊,链表长度不一啊。

    重点有三:sum = p + q + carry、新结点的值是sum%10、进位carry的值是sum/10.

    当一个栈为空时,此时令其对应的值为0就好啦。

    但是,这道题的答案链表是正序的,所以要用头插法,也就是,每次new出来的求和结点应当放在链表的头部。这个实现也不难,一开始我们令答案链表res为nullptr,然后每次都让new出来的结点tmp指向res,再让res=tmp就可以了。

    c++代码如下:

     1 /**
     2  * Definition for singly-linked list.
     3  * struct ListNode {
     4  *     int val;
     5  *     ListNode *next;
     6  *     ListNode(int x) : val(x), next(NULL) {}
     7  * };
     8  */
     9 class Solution {
    10 public:
    11     ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    12         stack<int> p, q;
    13         while(l1) p.push(l1->val), l1 = l1->next;
    14         while(l2) q.push(l2->val), l2 = l2->next;
    15         
    16         int carry = 0;
    17         ListNode* res = nullptr;
    18         while(p.size() || q.size() || carry){
    19             int m = 0, n = 0;
    20             if(p.size()) {
    21                 m = p.top();
    22                 p.pop();
    23             }
    24             if(q.size()) {
    25                 n = q.top();
    26                 q.pop();
    27             }
    28             int sum = m + n + carry;
    29             carry = sum / 10;
    30             ListNode* tmp = new ListNode(sum % 10);
    31             tmp->next = res;
    32             res = tmp;
    33         }
    34         return res;
    35     }
    36 };

    用递归来解的话,我们第一步要将两个链表补齐,为什么要补齐,因为之后的递归函数的需要。。那怎么补齐嘞,就是让短的那个链表前面补上0。既然是前面补0,那还是用上面所说的头插法,很简单吧~当然首先要遍历两个链表,来判断哪个长,哪个短哈哈,这个就不用说啦。

    然后就是最重要的递归函数了,我们这个递归函数呢,返回的是当前位置产生的进位噢!知道了函数的目的,就很好写这个函数了。当前位置的进位,要看当前位置结点的和,还有低位来的进位,对吧~低位来的进位,没错,就是在这里递归~边界条件是当链表为空时,最低位肯定是没有进位的,直接返回0即可。因为在计算进位的时候,是需要求和的,在这个过程中,答案链表res就可以得到了。

    如果最后carry不为0,那么肯定为1,再new一个值为1的结点,放到链表头部就好了~

    c++代码如下:

     1 /**
     2  * Definition for singly-linked list.
     3  * struct ListNode {
     4  *     int val;
     5  *     ListNode *next;
     6  *     ListNode(int x) : val(x), next(NULL) {}
     7  * };
     8  */
     9 class Solution {
    10 public:
    11     int addTwoNumbersHelper(ListNode* l1, ListNode* l2, ListNode* &res) {
    12         if(!l1) return 0;
    13         int carry = addTwoNumbersHelper(l1->next, l2->next, res);
    14         int sum = l1->val + l2->val + carry;
    15         ListNode* s = new ListNode(sum % 10);
    16         s->next = res;
    17         res = s;
    18         return sum / 10;
    19     }
    20     
    21     ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    22         ListNode* dummy = new ListNode(-1);
    23         ListNode* res = nullptr;
    24         auto p = l1, q = l2;
    25         int carry = 0, m = 0, n = 0;
    26         while(l1) l1 = l1->next, m++;
    27         while(l2) l2 = l2->next, n++;
    28         
    29         if(m > n){
    30             int k = m - n;
    31             dummy->next = q;
    32             while(k--){
    33                 auto tmp = new ListNode(0);
    34                 tmp->next = q;
    35                 q = tmp;
    36             }
    37         }
    38         else if(m < n){
    39             int k = n - m;
    40             dummy->next = p;
    41             while(k--){
    42                 auto tmp = new ListNode(0);
    43                 tmp->next = p;
    44                 p = tmp;
    45             }
    46             
    47         }
    48         carry = addTwoNumbersHelper(p, q, res);
    49         if(carry){
    50                 auto tmp = new ListNode(1);
    51                 tmp->next = res;
    52                 res = tmp;
    53         }
    54         return res;
    55     }
    56 };
  • 相关阅读:
    JChartFree创建饼形图
    JFreeChart设置点的颜色
    JChartFree使用散点图
    JChartFree常用数据集
    博客园安家了
    在Android中什么是异步执行;
    XmlPullParserException
    构造器的执行顺序
    Sqlite之contentProvider
    使用java获取歌曲的属性
  • 原文地址:https://www.cnblogs.com/hellosnow/p/12153384.html
Copyright © 2020-2023  润新知