加两个数字leetcode算法

时间:2019-11-13 23:29:04

标签: javascript

我正在执行以下leetCode问题:https://leetcode.com/problems/add-two-numbers/

我不确定为什么我的一个测试用例失败

所以问题是

  

您将获得两个非空链表,它们代表两个非负数   整数。这些数字以相反的顺序存储,每个数字   节点包含一个数字。将两个数字相加,然后将其返回为   链表。

     

您可以假设两个数字不包含任何前导零,除了   数字0本身。

我为它写了以下算法

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
const makeLinkedList = (inArr, i) => {
    if (i < 0) return null
    return { val:inArr[i], next:makeLinkedList(inArr, i-1)}
}


var addTwoNumbers = function(l1, l2) {
    let sum = 0
    let i = 1
    while(l1 || l2) {
        if (l1 && l2) {
            sum = sum + l1.val*i + l2.val*i
             l1 = l1.next
             l2 = l2.next
        } else {

        if (l1) {  
            sum = l1.val*i + sum
            l1 = l1.next
        }
        if (l2) {
            sum = l2.val*i + sum
            l2 = l2.next
        }    
      }
        i = i*10
    }
    const sumToString = sum.toLocaleString('fullwide', {useGrouping:false}); 
    return  makeLinkedList(sumToString, sumToString.length-1)
};

我在上述代码中使用while循环而不是递归调用函数的原因主要是为了使其更加优化。

无论如何,对于以下输入,我的测试用例失败

[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]
[5,6,4]

即我的输出将是[0,3,NaN,NaN,1]而不是[6,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]

请注意,leetCode编译器将在输入时将数组转换为链表。有人可以帮我弄清楚为什么我的输入可能会失败吗?

1 个答案:

答案 0 :(得分:1)

当JavaScript将scientific notation中的数字字符串化时,将使用+表示正指数。您看到的顺序是1E+30NaN代表+E(由于恢复了顺序)。实际上,您可以放一个console.log(sum)console.log(sumToString)并在不知道这一点的情况下抓住问题,仅查看其中的内容即可。

并非所有语言都告诉您它们可以存储的最大值而不会损失精度,但是JavaScript尤其如此,Number.MAX_SAFE_INTEGER包含值9 007 199 254 740 991,因此比9E+15还要多,远远少于1 + 1E+30(较长的数字)。

您应该做的是像在小学时一样增加数字:添加两位数字,写一位数字,然后查看是否有1可以携带到下一个数字对将要添加。

迭代版本:

function makeLinkedList(arr,i){
  i=i || 0;
  return i<arr.length?{val:arr[i], next:makeLinkedList(arr,i+1)}:null;
}

var addTwoNumbers = function(l1, l2) {
  var snt={next:null};
  var cur=snt;
  var carry=0;
  while(l1 || l2 || carry){
    cur.next={next:null};
    cur=cur.next;
    var sum=(l1?l1.val:0)+(l2?l2.val:0)+carry;
    if(sum<10){
      cur.val=sum;
      carry=0;
    } else {
      cur.val=sum-10;
      carry=1;
    }
    l1=l1?l1.next:null;
    l2=l2?l2.next:null;
  }
  return snt.next;
}

var a=[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1];
var b=[5,6,4];
console.log(addTwoNumbers(makeLinkedList(a),makeLinkedList(b)));
a=[9,9];
b=[1,9];
console.log(addTwoNumbers(makeLinkedList(a),makeLinkedList(b)));

递归版本:

function makeLinkedList(arr,i){
  i=i || 0;
  return i<arr.length?{val:arr[i], next:makeLinkedList(arr,i+1)}:null;
}

var addTwoNumbers = function(l1, l2, carry) {
  if(!(l1 || l2 || carry))
    return null;
  carry=carry || 0;
  var sum=(l1?l1.val:0)+(l2?l2.val:0)+carry;
  return {
    val: sum % 10,
    next: addTwoNumbers(l1?l1.next:null,l2?l2.next:null,sum>9?1:0)
  };
}

var a=[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1];
var b=[5,6,4];
console.log(addTwoNumbers(makeLinkedList(a),makeLinkedList(b)));
a=[9,9];
b=[1,9];
console.log(addTwoNumbers(makeLinkedList(a),makeLinkedList(b)));