IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> [JavaScript 刷题] 哈希表 - 和为 K 的子数组 leetcode 560 -> 正文阅读

[数据结构与算法][JavaScript 刷题] 哈希表 - 和为 K 的子数组 leetcode 560

[JavaScript 刷题] 哈希表 - 和为 K 的子数组, leetcode 560

github repo 地址: https://github.com/GoldenaArcher/js_leetcode,Github 的目录 大概 会更新的更勤快一些。

题目地址:560. Subarray Sum Equals K

题目

如下:

Given an array of integers nums and an integer k, return the total number of subarrays whose sum equals to k.

A subarray is a contiguous non-empty sequence of elements within an array.

解题思路

暴力解

这个解法会超时,但是我觉得这个解法说的还是挺清楚的,还给了一个比较好的初始思路。

这种将所有的前置和存储在一个数组中,然后遍历两边前置去计算有多少个子数组。

[1, 2, 3] 为例,前置和数组的值为:[ 0, 1, 3, 6 ]

数组和的长度比数组多一个是当下标为 0 时,数组和自然为 0。

当下标为 1 时,当前值为 nums[0] + sums[0]

当下标为 2 时,,当前值为 nums[1] + sums[1]

以此类推。

总体上来说就是将所有的前置和相加,最后用进行双重遍历,找到 sums[i + j] - sums[i] === k 出现过多少次即可。

哈希表

哈希表的解法一定程度上来说是 2 sum 的变种,2 sum 在 map 中获取的是 t a r g e t ? n u m s [ i ] target - nums[i] target?nums[i] 存储的键值对是 ( n u m s [ i ] , i ) (nums[i], i) (nums[i],i),这里获取的则是 s u m ? k sum - k sum?k,其中 s u m sum sum 为前数和,存储的键值对为 ( s u m , m a p . g e t ( s u m ) + 1 ) (sum, map.get(sum) + 1) (sum,map.get(sum)+1)

依旧以官方题目中的 nums = [1, 2, 3], k = 3 为例:

  1. 初始化时

    map 的值为: { ( 0 , 1 ) } \{(0, 1)\} {(0,1)},原因与暴力解中一样

  2. 当下标为 0 时

    此时在 map 中搜索 s u m ? k sum - k sum?k,即 -2。map 中并不包含这个值,继续下一步操作

    map 的值为: { ( 0 , 1 ) , ( 1 , 1 ) } \{(0, 1), (1, 1)\} {(0,1),(1,1)}

  3. 此时下标为 1

    此时在 map 中搜索 s u m ? k sum - k sum?k,即 0, map 中可以取得 ( 0 , 1 ) (0, 1) (0,1),所以 counter += map.get(sum - k)

    map 的值为: { ( 0 , 1 ) , ( 1 , 1 ) , ( 3 , 1 ) } \{(0, 1), (1, 1), (3, 1)\} {(0,1),(1,1),(3,1)}

    找到 s u m ? k sum - k sum?k 即代表当前子数组肯定能找到这样的一个组合,也就是 [1, 2]

  4. 此时下标为 2

    此时在 map 中搜索 s u m ? k sum - k sum?k,即 3, map 中可以取得 ( 3 , 1 ) (3, 1) (3,1),所以 counter += map.get(sum - k)

    map 的值为: { ( 0 , 1 ) , ( 1 , 1 ) , ( 3 , 1 ) , ( 6 , 1 ) } \{(0, 1), (1, 1), (3, 1), (6, 1)\} {(0,1),(1,1),(3,1),(6,1)}

最终获得结果为 2.

关于关于出现包含不止一个子数组的情况,可以参考 nums = [1,-1,0], k = 0 这个案例。

  1. 初始化时

    map 的值为: { ( 0 , 1 ) } \{(0, 1)\} {(0,1)}

  2. 当下标为 0

    此时在 map 中搜索 s u m ? k sum - k sum?k,即 -1。map 中并不包含这个值,继续下一步操作

    map 的值为: { ( 0 , 1 ) , ( 1 , 1 ) } \{(0, 1), (1, 1)\} {(0,1),(1,1)}

  3. 当下标为 1

    此时在 map 中搜索 s u m ? k sum - k sum?k,为 0,map 中包含这个键,因此 counter += 1

    map 的值为: { ( 0 , 2 ) , ( 1 , 1 ) } \{(0, 2), (1, 1)\} {(0,2),(1,1)}

  4. 当下标为 2

    此时在 map 中搜索 s u m ? k sum - k sum?k,为 0,map 中包含这个键,因此 counter += 1

    注意,这里会出现 2 是因为有两个数组可以实现当前值:

    1. [1, -1, 0]
    2. [0]

    map 的值为: { ( 0 , 3 ) , ( 1 , 1 ) } \{(0, 3), (1, 1)\} {(0,3),(1,1)}

使用 JavaScript 解题

暴力解法

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
var subarraySum = function (nums, k) {
  const n = nums.length;
  const sums = new Array(n + 1).fill(0);

  for (let i = 1; i <= n; i++) {
    sums[i] = sums[i - 1] + nums[i - 1];
  }

  let counter = 0;

  for (let i = 0; i < n; i++) {
    for (let j = i; j < n; j++) {
      if (sums[j + 1] - sums[i] === k) counter++;
    }
  }

  return counter;
};

哈希表解法

var subarraySum = function (nums, k) {
  const map = new Map([[0, 1]]);

  let counter = 0,
    sum = 0;

  for (const num of nums) {
    sum += num;
    if (map.has(sum - k)) counter += map.get(sum - k);

    if (map.has(sum)) map.set(sum, map.get(sum) + 1);
    else map.set(sum, 1);
  }

  return counter;
};
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-06-29 19:19:22  更:2022-06-29 19:21:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 23:32:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码