zoukankan      html  css  js  c++  java
  • 链表操作 模拟问题

    问题:

            两个链表模拟大整数加法。

        1-》2-》3  + 4-》5 = 1-》6-》8

    解答:

      1)使用递归实现。

      比直接使用迭代实现更好。

      加法需要从最低位开始,在使用递归实现时,会先递归到最底层(len==1)的情况,然后依次返回到上一层并伴随返回进位数。这样就比直接的迭代实现节省了每次定位同层节点的时间。

     1 int length(const Node* head)
     2 {
     3     int length = 0;
     4     while(head != NULL)
     5     {
     6         length++;
     7         head = head->next;
     8     }
     9 
    10     return length;
    11 }
    12 
    13 //headA指的链表长度不小于headB
    14 int __add(Node* headA, int lenA, Node* headB, int lenB)
    15 {
    16     int sum = -1;
    17     if(lenA == 1)
    18         sum = headA->data + headB->data;
    19     else if(lenA > lenB)
    20         sum = headA->data + __add(headA->next, --lenA, headB, lenB);
    21     else//现在只剩下lenA == lenA的情况
    22         sum = headA->data + headB->data + __add(headA->next, --lenA, headB->next, --lenB);
    23 
    24     headA->data = sum % 10;
    25     return sum / 10;
    26 }
    27 
    28 Node* add(Node* listA,Node* listB)
    29 {
    30     if(listA == NULL)
    31         return listB;
    32     if(listB == NULL)
    33         return listA;
    34 
    35     int lenA = length(listA);
    36     int lenB = length(listB);
    37     Node* longer = listA;
    38     Node* shorter = listB;
    39     if(lenA <lenB)
    40     {
    41         longer = listB;
    42         shorter = listA;
    43     }
    44 
    45     int carry = __add(longer, lenA, shorter, lenB);
    46     if(carry != 0)
    47     {
    48         Node* head = new Node(carry);
    49         head->next = longer;
    50         longer = head;
    51     }
    52 
    53     return longer;
    54 }

      

      2)迭代实现

      

        直接的迭代实现较为浪费时间,在由尾向头坐加法时,每次需要遍历过程来获取某一个位置的节点,花费O(n)的时间;

        可以使用堆栈,讲两个链表的同层节点压入依次压入堆栈。然后再依次弹出、计算。这个过程其实就和函数递归调用一样的了。在此不表。

      3)逆转实现【贺斌启发下完成】

        如果有链表1-》2-》3-》NULL 和 链表4-》5-》NULL,此时我们的相加操作代表123 + 45。

        如果我们将链表修改为3-》2-》1-》NULL和5-》4-》NULL,这样就可以从左向右的相加了!之后再将搜求的链表反转就可以了。

        反转操作,我们之前已经讲解过了,可以达到O(n)的时间复杂度,而相加操作耗时O(n)。总的时间复杂度为O(n)。

    问题:

            两个链表模拟大整数加法。

        1-》2-》3  + 4-》5 = 5-》7-》3

        题目来自:Leetcode -- Add Two Numbers

    解答:

      

     1 ListNode *addTwoNumbers(ListNode *l1, ListNode *l2)
     2 {
     3     ListNode newHead(0);
     4     ListNode* p = &newHead;
     5 
     6     int  carry = 0;
     7     while(l1 || l2 || carry)
     8     {
     9         int n1 = (l1 == NULL)?0:l1->val;
    10         int n2 = (l2 == NULL)?0:l2->val;
    11         
    12         //这里我们产生新的节点来存储和
    13         //而非直接使用p来存储
    14         //直接使用p来存储的时候,还需要传递prev指针来指向p。
    15         p->next = new ListNode((n1 + n2 + carry)%10);
    16         p = p->next;
    17 
    18         carry = (n1 + n2 + carry)/10;
    19 
    20         if(l1)
    21             l1 = l1->next;
    22 
    23         if(l2)
    24             l2 = l2->next;
    25     }
    26     return newHead.next;
    27 }

      

  • 相关阅读:
    关于Python装饰器内层函数为什么要return目标函数的一些个人见解
    多项式拟合与线性回归
    numpy基本方法总结 --good
    numpy中的convolve的理解
    最容易理解的对卷积(convolution)的解释
    Python之numpy基本指令
    线性回归原理小结
    矩阵的导数与迹
    【MyBatis学习14】MyBatis和Spring整合
    【MyBatis学习13】MyBatis中的二级缓存
  • 原文地址:https://www.cnblogs.com/carlsama/p/4126470.html
Copyright © 2011-2022 走看看