【JS攻略Leetcode】No.2. Add Two Numbers(两数相加)

引言:用Js攻略leetcode中的算法,将会介绍自己的思路和注意点,一边学习一边愉快刷题呀。

问题1:

给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

思考:

  1. 342 + 465 = 807 也就是位位相加,注意一下每一位相加要加上进位,最后一次两个链表都到了结束,也要注意一下有没有进位:比如 99 + 1 = 100;
  2. 注意链表怎么把每个节点连接起来:每次生成一个listnode元素,通过当前listnode的下一个元素(cur_node.next)连城链。
  3. 最后返回一个列表,所以要给个头(result)指示列表起始的位置,再通过cur_node链接起链表串

代码:

/**
* Definition for singly-linked list.
* function ListNode(val) {
*     this.val = val;
*     this.next = null;
* }
*/

var addTwoNumbers = function(l1, l2) {
    var val1 = 0;
    var val2 = 0;
    var carry = 0;//进位
    var result = null;//返回值
    var cur_node = null;

    var sumWithCarry = function(sum) {
        if(sum >= 10) {
            carry = 1;
            sum = sum - 10;
        } else {
            carry = 0;
        }
        return sum;
    }

    if(l1 || l2) {
        val1 = l1 ? l1.val : 0;
        val2 = l2 ? l2.val : 0;
        l1 = l1 ? l1.next : null;
        l2 = l2 ? l2.next : null;
        cur_node = new ListNode(sumWithCarry(val1 + val2));
        result = cur_node;
        while(l1 || l2) {
            val1 = l1 ? l1.val : 0;
            val2 = l2 ? l2.val : 0;
            l1 = l1 ? l1.next : null;
            l2 = l2 ? l2.next : null;
            cur_node.next = new ListNode(sumWithCarry(val1 + val2 + carry));
            cur_node = cur_node.next;
        }
        if(carry != 0) {
            cur_node.next = new ListNode(sumWithCarry(carry));
        }
    }
    return result;
};

问题2:

如果链表中的数字不是按逆序存储的呢?例如:
(3 -> 4 -> 2) + (4 -> 6 -> 5) = 8 -> 0 -> 7
符合人类观察的习惯: 342+465 = 807

思路:

  1. 思路1也是位位相加, 将两个列表中的值存入数组中:result_array = [3+4, 4+6, 2+5] = [7,10, 7], 再考虑进位为题变成 [ 8, 0, 7 ], 最后生成listnode连接起来。但是这种方法在列表不等长的情况下是不可行了,可跳过去看最后。
var addTwoNumbers = function(l1, l2) {
    var result_array = [];
    var result = null;//返回值
    var cur_node = null;
    var val1 = 0;
    var val2 = 0;
    while(l1 || l2) {
        val1 = l1 ? l1.val : 0;
        val2 = l2 ? l2.val : 0;
        l1 = l1 ? l1.next : null;
        l2 = l2 ? l2.next : null;
        result_array.push(val1 + val2)
    }
    for (var i = result_array.length - 1; i >= 0; i--) {
        if(result_array[i] >= 10) {
            result_array[i] = result_array[i] - 10;
            if(i > 0) {
                result_array[i -1] = result_array[i-1] + 1;
            } else {
                result_array.unshift(1);
                return;
            }
        }
    }
    if( result_array.length ){
        result = new ListNode(result_array[0]);
        cur_node = result;
        if(result_array.length > 1) {
            for (var i = 1; i <= result_array.length - 1; i ++) {
                cur_node.next = new ListNode(result_array[i]);
                cur_node = cur_node.next;
            }
        }
    }
    
    return result;
};

乍看起来非常完美,但是遇到了一个极其重要的逻辑问题:在处理两列表等长时这个方法可行,但是不等长时相加错误,比如: [9,9] + [2] = [9, 11]=[1,0,1], 但上述办法算出来是[11,9]=[1,1,9],所以在两列表不等长时,必须将相加位位置对齐,在另一个列表元素数组前面加上很多0;但是我觉得这种方式时间复杂度太高了。

  1. 思路2:然后我想为什么不能将它们变为数字再进行相加呢?[9,9] + [2] = 99 + 2 = 101 = [1,0,1]

代码:

var addTwoNumbers = function(l1, l2) {
    var result_array = [];
    var result_sum = 0;
    var result1 = 0;
    var result2 = 0;
    var result = null;//返回值
    var cur_node = null;
    
    var val1 = 0;
    var val2 = 0;

    while(l1 || l2) {
        val1 = l1 ? l1.val : 0;
        l1 = l1 ? l1.next : null;
        result1 = val1 + result1*10;
        val2 = l2 ? l2.val : 0;
        l2 = l2 ? l2.next : null;
        result2 = val2 + result2*10;
    }
    result_sum = result1 + result2;
    while(result_sum >= 10) {
        result_array.push(result_sum % 10);
        result_sum = ~~(result_sum / 10);
    }
    result_array.push(result_sum);

    if( result_array.length ){
        for (var i = result_array.length - 1; i >= 0; i--) {
            if(i == result_array.length - 1) {
                result = new ListNode(result_array[i]);
                cur_node = result;
            } else {
                cur_node.next = new ListNode(result_array[i]);
                cur_node = cur_node.next;
            }
        }
    }
    return result;
};
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容