leetCode Hot 算法学习记录 JS

161 阅读3分钟

前言

感谢各位催学社的内卷王们的内卷,在各位卷王的带动下,开始学习,拓展自己。 欢迎大家来 催学社 一起学习。可以通过关注B站up 阿崔cxr。 持续更新中。。。

1. 两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答案。

image.png

思路:

1、暴力的两个for循环,两两相加,返回结果。

var twoSum = function(nums, target) {
    for(let i= 0; i < nums.length; i++) {
        for(let j = i + 1 ; j<nums.length; j++) {
            if( nums[i] + nums[j] === target ) {
                return [ i, j ]
            }
        }
    }
};

2、使用 target 减去当前循环的内容,得到剩余需要查找的数,然后在map中寻找对应的值,没有就存入map中备用。

var twoSum = function(nums, target) {
    map = new Map()
    for(let i = 0; i < nums.length; i++) {
        x = target - nums[i]
        if(map.has(x)) {
            return [map.get(x),i]
        }
        map.set(nums[i],i)
    }
};

2. 两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

image.png

思考点:链表。前端中什么是链表? 学习文章

核心是一个嵌套的数据结构。

image.png

链表实现function :

 function ListNode(val, next) {
         this.val = (val===undefined ? 0 : val)
         this.next = (next===undefined ? null : next)
     }

理解了链表的结构,来实现一下题目。

思路:

画图得知,解题思路为,循环链表,让链表的对位相加,然后调用 next 走下一个链表位。

image.png

指定两个参数,表示当前链表的值

let p1 = l1 // 指向链表1的头部
let p2 = l2 // 指向链表2的头部

相加的时候,如果满足10,进位。设置一个值存储

let carry = 0

循环两个链表

// 只要两个链表中当前位置有值,就继续循环
 while(p1 || p2) {
       // 因为两个链表长度可能不同 判断一下当前位置是否有值,如果没有默认成0, 
         const v1 = p1 ? p1.val : 0
         const v2 = p2 ? p2.val : 0
         const val = v1 + v2 + carry  // 两数 + 进位
         carry = Math.floor(val / 10) // 给进位赋值,看当前结果有没有过 10
         p3.next = new ListNode(val % 10) // 进位后个位数就是当前的值
         // 指针继续往后走, 利用 Object 指向赋值
         if(p1) p1 = p1.next
         if(p2) p2 = p2.next
         p3 = p3.next
     }

特殊情况: 当两个链表相加 出现新的一位进位 如 [ 2, 2, 7 ] + [ 5, 6, 4 ] 这种加到最后一个还有进位的情况。

if(carry) {  p3.next = new ListNode(carry)  }
全部代码:
 var addTwoNumbers = function(l1, l2) {
     const l3 = new ListNode(0) // 定义一个链表来存放结果
     let p1 = l1 // 指向链表1的头部
     let p2 = l2 // 指向链表2的头部
     let p3 = l3
     let carry = 0 // 进位的数,即留到下一轮相加的数
     while(p1 || p2) {
         // 这两个三元判断是为了防止相加的两个数长度不同
         const v1 = p1 ? p1.val : 0
         const v2 = p2 ? p2.val : 0
         const val = v1 + v2 + carry
         carry = Math.floor(val / 10) // 相加后的十位数
         p3.next = new ListNode(val % 10) // 相加后的个位数
         // 指针继续往后走,利用了 Object 的指向赋值
         if(p1) p1 = p1.next
         if(p2) p2 = p2.next
         p3 = p3.next
     }
     // 处理特殊情况:如[2,2,7] + [5,6,4]这种加到最后一个还有进位的情况
     if(carry) {
         p3.next = new ListNode(carry)
     }
     return l3.next
 };