算法 :两数相加

 一、比较恶心的算法逻辑:

最开始因为对链表不了解,所以我最开始想到的是 类似两个数组相加;把两个链表遍历成数组然后倒过来转换成数字,相加后再反转数组;

比如:arr1 = [2,8,6] ;arr2 = [9,5,2]

        把两个数组  reverse()  之后    join()   一下

        不就能得到 '682'  和 '259' 了吗!

        Number() 之后   在相加   这不就得到 707 吗!

        最后就是 split()  一下  就可以得出结果了!

!!! 但是这是 链表 不是 数组; return 出来的数据格式不对,就一直报错就很恶心;

最后没办法,只能改呗;

        我就把两个链表遍历出来各自生成 一个 数组 

        遍历最长的数组  把他们的两个 每一项的值   相加  然后生成 链表

本来是打算是 反转数组->转化数字->计算数字->再反转成数组  -> 生成链表;但是写到一半嫌麻烦就直接一项一项的生成链表了

        因为链表每一项 是单位数的数组 有进位的时候就要另外存储取来 

        下一次计算的时候加上去;for循环中还要判断一下最后一次计算 有没有进位 

        如果有的话就要在链表后面再加一位,没有就直接导出;

        反正就挺恶心的!!  

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var addTwoNumbers = function(l1, l2) {
    let arr1 = []
    let arr2 = []

    for(let i = 0; i >-1 ;i++ ){
        if(l1){
            arr1.push (l1.val? l1.val : 0)
        }else{
            break;
        }
         if (l1) {
            l1 = l1.next;
        }
    }
    for(let i = 0; i >-1 ;i++ ){
        if(l2){
            arr2.push (l2.val? l2.val : 0);
        }else{
            break;
        }
        if(l2){
            l2 = l2.next;
        }
    }

    const len = Math.max(arr1.length,arr2.length)

    let k = 0;
    let list = null;
    let tail =null;
    for(let i = 0;i<len || k !=0;i++){
        const p1 = arr1[i] ? arr1[i] : 0;
        const p2 = arr2[i] ? arr2[i] : 0;
        const val = p1 + p2 + k;
        k = Math.floor( val /10 );
        if(!list){
            list = tail = new ListNode(val % 10);
        }else{
            tail.next = new ListNode(val % 10);
            tail = tail.next;
        }
    }
    return list
};

二、看了链表表的知识和官方的题解后的算法逻辑

唯一的难点就是 进位的计算  额外定义一个存储器  把进位的值 单独存储   每一次计算的值的时候把上一次计算存储 的 进位值  拿过来 加一起;然后把当前计算过后的 进位值 更新到存储器中,用于下一次计算;最后一次计算的时候判断一下存储器中进位的值还有没有?有就再在链表的最后一位加上,没有就直接返回,就OK了;

效率还是比较高的,相比较于上面那个转来转去的 方便多了;

主要是对链表之类 的知识了解太少,数组倒是理解的挺深的;

var addTwoNumbers = function(l1, l2) {
    let listNode = null;
    let tail = null;
    let k = 0;
    while (l1 || l2) {
        // 获取 两个链表  当前节点的值  和 进位的值 求和
        const p1 = l1 ? l1.val : 0; // l1.val 可能为 null
        const p2 = l2 ? l2.val : 0; // l2.val 可能为 null
        const val = p1 + p2 + k;

        //计算出进位的值  
        k = Math.floor(val / 10);

        //链接链表  listNode 为 链表的头部 
        // tail 为 即将 叠加 到链表上 每一项的临时存储器
        if (!listNode) {
            listNode = tail = new ListNode(val % 10); // 设置listNode为链表的头
        } else {
            tail.next = new ListNode(val % 10);  //为链表的最后一项 注入数据
            tail = tail.next;    // 增长 链表
        }

        
        if (l1) {
            l1 = l1.next;
        }
        if (l2) {
            l2 = l2.next;
        }

    }

    if (k > 0) {
        tail.next = new ListNode(k);
    }


    return listNode;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值