【问题标题】:Add to numbers represented by a linked list - Edge case添加到由链表表示的数字 - 边缘情况
【发布时间】:2013-06-21 00:22:50
【问题描述】:

我正在阅读 Gayle Laakmann 在第 108 页的书 Crack The Coding Interview 中的链表表示的两个数字相加算法。如果您没有这本书,问题、算法和代码如下:

问题

你有两个由一个链表表示的数字,其中每个节点 包含一个数字。数字以相反的顺序存储,例如 1 的数字位于列表的首位。写一个函数 将两个数字相加,然后将 um 作为链表返回。

示例

输入:(3->1->5),(5->9->2)

输出:8->0->8

算法

  1. result.data = (node1 + node2 +earlier carry) % 10
  2. 如果node1 + node2 > 10,则携带1到下一个加法
  3. 添加两个节点的尾部,沿进位传递

代码

LinkedListNode addLists(LinkedListNode l1, LinkedListNode l2, int carry) {  
if (l1 == null && l2 == null) {     
    return null;    
}   
LinkedListNode result = new LinkedListNode(carry, null, null);  
int value = carry;  
if (l1 != null) {       
    value += l1.data;   
}   
if (l2 != null) {       
    value += l2.data;   
}   
result.data = value % 10;   
LinkedListNode more = addLists(l1 == null ? null : l1.next, l2 == null ? null : l2.next, value > 10 ? 1 : 0);   
result.setNext(more);   
return result;
}

看到if (l1 == null && l2 == null) 后想到的显而易见的事情是,如果两个数字都为空并且仍然有进位怎么办 - 就像我们添加 999 + 999 时一样。这不会导致错误的答案吗?如果这导致正确的答案,我看不出如何。如果这导致错误的答案,我们怎样才能得到正确的答案?将前几行更改为

LinkedListNode addLists(LinkedListNode l1, LinkedListNode l2, int carry = null) {   
if (l1 == null && l2 == null) {     
    return carry;   
}

做这个伎俩?

【问题讨论】:

  • 是的,除了你必须返回一个新的 LinkedListNode。
  • 哦,我差点忘了!

标签: algorithm linked-list


【解决方案1】:

条件应该是:

value > 9 ? 1 : 0 

在以下递归调用中:

LinkedListNode more = addLists(l1 == null ? null : l1.next, l2 == null ? null : l2.next, value > 10 ? 1 : 0);
 // space

【讨论】:

    【解决方案2】:

    这是我的有效解决方案:

    public class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        return addTwoNumbers(l1, l2, 0);
    }
    
    public ListNode addTwoNumbers(ListNode l1, ListNode l2, int carry) {
        int value;
        if(carry > 0) {
            // handle negative values for carry
           value = carry;
        } else {
           value = 0; 
        }
        if(l1 == null && l2 == null){
            if(value > 0) {
                // here we have only carry to bother.
                // if it is zero, no need to create node
                return new ListNode(value);
            } else {
                return null;
            }
        }
        if(l1 != null){
            value += l1.val;
        }
        if(l2 != null){
            value += l2.val;
        }
        carry = value/10;
        ListNode n1 = new ListNode(value%10);
        n1.next = addTwoNumbers(l1 != null ? l1.next : null, l2 != null ? l2.next : null, carry);
        return n1;
    }
    

    }

    【讨论】:

      【解决方案3】:

      我使用 DList 的解决方案!

      public class DListNode {
      public int item;
      public DListNode prev;
      public DListNode next;
      
       DListNode() {
          item = 0;
          prev = null;
          next = null;
      }
      
      public DListNode(int i){
          item = i;
          prev = null;
          next = null;
      
      }
      

      }

      二等:

      public class DList {
      protected DListNode head;
      protected DListNode tail;``
      protected long size;
      
      public DList() {
          head = null;
          tail = null;
          size = 0;
      }
      
      public DList(int a) {
          head = new DListNode();
          tail = head;
          head.item = a;
          size = 1;
      
      }
      
      public DList(int a, int b) {
          head = new DListNode();
          head.item = a;
          tail = new DListNode();
          tail.item = b;
          head.next = tail;
          tail.prev = head;
          size = 2;
      
      }
      
      public void insertFront(int i) {
          if (size == 0) {
              head = new DListNode(i);
              tail = head;
          } else {
              DListNode temp = new DListNode(i);
              head.prev = temp;
              temp.next = head;
              head = temp;
          }
          size++;
      }
      
      public String toString() {
          String result = "[  ";
          DListNode current = head;
          while (current != null) {
              result = result + current.item + "  ";
              current = current.next;
          }
          return result + "]";
      }
      
      public long getSize() {
          return size;
      }
      
      public DListNode getHead() {
          return head;
      }
      
      public DListNode getTail() {
          return tail;
      }
      
      public DList addList(DList lst1, DList lst2) {
          DList result = new DList();
      
          DListNode tail1 = lst1.getTail();
          DListNode tail2 = lst2.getTail();
          int carry = 0;
      
          if (lst1 == null || lst2 == null) {
              return null;
          }
      
          if (lst1.getSize() != lst2.getSize()) {
              if (lst1.getSize() < lst2.getSize()) {
                  long diff = lst2.getSize() - lst1.getSize();
                  long a = 0;
                  while (a < diff) {
                      lst1.insertFront(0);
                      a++;
                  }
      
              } else {
                  long diff = lst1.getSize() - lst2.getSize();
                  long a = 0;
                  while (a < diff) {
                      lst2.insertFront(0);
                      a++;
                  }
      
              }
          }
          int a = 0;
          int resultValue;
          while (a <= lst1.getSize()) {
              if (tail1 != null && tail2 != null) {
                  int l1 = tail1.item;
                  int l2 = tail2.item;
                  int sum = carry + l1 + l2;
      
                  if (a == lst1.getSize() - 1) {
                      resultValue = sum % 10;
                      carry = 1;
                      result.insertFront(carry);
                      result.insertFront(resultValue);
      
                  } else if (sum >= 10) {
                      resultValue = sum % 10;
                      carry = 1;
                      result.insertFront(resultValue);
      
                  }
      
                  else {
                      resultValue = sum;
                      carry = 0;
                      result.insertFront(resultValue);
      
                  }
                  //result.insertFront(resultValue);
                  tail1 = tail1.prev;
                  tail2 = tail2.prev;
      
              }
              a++;
          }
      
          System.out.println("List1 is: " + lst1.toString());
          System.out.println("List2 is: " + lst2.toString());
      
          return result;
      }
      
      public static void main(String[] args) {
          DList d1 = new DList();
          DList d2 = new DList();
      
          d1.insertFront(1);
          d1.insertFront(5);
          d1.insertFront(3);
      
          d2.insertFront(4);
          d2.insertFront(5);
          d2.insertFront(7);
      
          DList d3 = new DList();
          System.out.println(d3.addList(d1, d2));
      
      }
      

      }

      【讨论】:

        【解决方案4】:
        Node* addReversed(Node *l1, Node *l2, int carry) {
            if (l1 == NULL && l2 == NULL && carry == 0) return NULL;
        
            int value = carry;
            if (l1 != NULL)
                value += l1->data;
            if (l2 != NULL)
                value += l2->data;
        
            Node *answer = new Node(value%10);
        
            if (l1 != NULL || l2 != NULL) {
                Node *temp = addReversed(l1 != NULL ? l1->next : NULL, l2 != NULL ? l2->next : NULL, value >= 10 ? 1 : 0);
                answer->next = temp;
            } else {
                if (value >= 10) {
                    Node *temp = new Node(1);
                    answer->next = temp;
                }
            }
            return answer;
        }
        

        基本上,最后一个 if 条件检查加法是否结束并且是否还有进位。如果是这种情况,则将其添加到自己的节点并附加到答案中。

        【讨论】:

          【解决方案5】:

          我使用 Python3 的解决方案

          class Node:
          def __init__(self, value):
              self.value = value
              self.next = None
          
          class LinkedList:
          def __init__(self):     
              self.head = None
              self.tail = None
          
          def addNode(self, inse):        
              nde = Node(inse)       
              if self.head == None:
                  self.head = nde
                  self.tail = nde
              else:
                  self.tail.next = nde
                  self.tail = nde
          
          def __str__(self):
              nodestore = [str(self.head.value)]
              index = self.head
              while index.next != None:
                  index = index.next
                  nodestore.append(str(index.value))
              return "->".join(nodestore)
          
          def addTwo(self, fi, se):
              self.head = None
              self.tail = None
              carry = 0
          
              while (fi is not None or se is not None):
                  fdata = 0 if fi is None else fi.value
                  sdata = 0 if se is None else se.value
                  Sum = carry + fdata + sdata
          
                  carry = 1 if Sum >= 10 else 0
          
                  Sum = Sum if Sum < 10 else Sum % 10
          
                  temp = Node(Sum)
          
                  if self.head == None:
                      self.head = temp
                  else:
                      self.tail.next = temp
          
                  self.tail = temp
          
                  if fi is not None:
                      fi = fi.next
                  if se is not None:
                      se = se.next
          
              if carry > 0:       #for first digit = 1
                  self.tail.next = Node(carry)        
          
          def randomLinkedList(leng, min, max):
          from random import randint
          rll = LinkedList()
          for i in range(leng):
              value = randint(min, max)
              rll.addNode(value)
          return rll
          
          l1 = randomLinkedList(3,0,9)
          l2 = randomLinkedList(3,0,9)
          print (l1)
          print (l2)
          res = LinkedList()
          res.addTwo(l1.head, l2.head)
          print (res)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-12-25
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多