JS算法之两数之和与两数相加

529 阅读2分钟

这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战

两数之和

Hot100 1.两数之和

难度:简单

题目:leetcode-cn.com/problems/tw…

给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例1:

 输入:nums = [2,7,11,15], target = 9
 输出:[0,1]
 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1]

示例2:

 输入:nums = [3,2,4], target = 6
 输出:[1,2]

示例3:

 输入:nums = [3,3], target = 6
 输出:[0,1]

提示:

  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • 只会存在一个有效答案

进阶:你可以想出一个时间复杂度小于O(n^2​)的算法吗?

题解

法一 暴力法

暴力法匹配两数之和等于目标值的两个下标。

 /**
  * @param {number[]} nums
  * @param {number} target
  * @return {number[]}
  */
 const twoSum = (nums, target) => {
   const len = nums.length;
   for(let i = 0; i < len; i++){
       for(let j = i+1; j < len; j++){
           if(nums[i]+nums[j] === target){
               return [i,j];
           }
       }
   }
 }

时间复杂度:O(n^2)

空间复杂度:O(1)

法二 哈希表

利用哈希表将数组中的数据存在哈希表中,同时在哈希表中查找差值及其下标。

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

时间复杂度:O(n)

空间复杂度:O(n)

两数相加

Hot100 2.两数相加

难度:中等

题目:leetcode-cn.com/problems/ad…

给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字0之外,这两个数都不会以0开头。

示例1:

img

 输入:l1 = [2,4,3], l2 = [5,6,4]
 输出:[7,0,8]
 解释:342 + 465 = 807.

示例2:

 输入:l1 = [0], l2 = [0]
 输出:[0]

示例3:

 输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
 输出:[8,9,9,9,0,0,0,1]

提示:

  • 每个链表中的节点数在范围 [1, 100]
  • 0 <= Node.val <= 9
  • 题目数据保证列表表示的数字不含前导零

题解

模拟法

模拟两个数相加,通过判断链表上节点是否存在来进行循环,相加若有进位的话,要考虑进位,若某个链表为空的话,其上的值要用0来代替。

 /**
  * 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 addOne = 0; // 表示有进位需要加1
     let sum = new ListNode(0); // 创建一个新的链表
     const head = sum;
     while(addOne || l1 || l2){
         let v1 = l1 !== null ? l1.val : 0;
         let v2 = l2 !== null ? l2.val : 0;
         let sumValue = v1 + v2 + addOne;
 ​
         addOne = sumValue >= 10 ? 1 : 0;
         sum.next = new ListNode(sumValue % 10); // 将求余后的值放入链表
         sum = sum.next;
         if(l1) l1 = l1.next;
         if(l2) l2 = l2.next;
     }
     return head.next;
 };

时间复杂度:O(max(m,n)),其中m、n为两个链表的长度

空间复杂度:O(1)


坚持每日一练!前端小萌新一枚,希望能点个+在看哇~