前缀和+哈希表:联手合击Leetcode 560.和为k的子数组

2024-03-07 02:44

本文主要是介绍前缀和+哈希表:联手合击Leetcode 560.和为k的子数组,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 

子数组是数组中元素的连续非空序列。

 

示例 1:

输入:nums = [1,1,1], k = 2
输出:2

示例 2:

输入:nums = [1,2,3], k = 3
输出:2

081dcccf0088436498f11e2ea1db04b2.png

思路

因为这道题刚开始确实被刺了博主一把,所以有感而发下面多啰嗦两句警示大家。

仔细观察题目可以发现,表面人畜无害的题目背地里却暗藏杀机,博主在看到题目的第一瞬间扫描到 子数组 和为k 看了两个示例 顿时大喜,直接上手以迅雷不及掩耳之势敲出滑动窗口解法,试图直接通过left与right两员大将拿下此题,不出意外的话果然出意外了,在再次看到数据范围后果断将两位大将收回。另寻他法。

这里解释一下,滑动窗口是在题目所给数据具有单调性时,通过准确的把握单调性来减少遍历或枚举的次数从而达到降低时间复杂度的目的,而本题数据有正有负,且为乱序排列,我们无法准确把握每组数据的单调性,所以无法使用滑动窗口来进行解题。

而结合求和,子数组,和样例等种种特点排除滑动窗口后,前缀和无疑时此时最适合的方式。

可是涉及到子序列的问题,即使直接求出前缀和数组,如果进行简单的遍历再去一个个计算,那么复杂度直逼O(n^2),加上构造前缀和数组,复杂度还不如直接暴力枚举。所以需要在前缀和基础上进行优化,题目让求有多少个子集,那可以抽象为第i个结点之前有多少个符合和为k的结点,然后一个节点一个节点去求,从而可以再抽象为,第i个位置之前,有多少个节点等于第i个节点的前缀和-k。及判断在[0,i-1]区间内有多少个前缀和等于sum[i]-k;

因为数据没有单调性,所以i之前可能出现多个子串符合条件,而每次查找会消耗掉多余的时间,所以直接创建一个哈希表,对应进行查找,每次先查找再插入当前节点

注意:[0,i-1]==sum[i]-k,判断是否存在可以分为以下情况:

1、从0加到 在nums数组中的那位刚好等于k,那sum[i]-k就是0;此时需要到0,-1区间去找,所以直接将哈希表0位置初始化成1,当这种情况出现时直接加上。

2、从0到i中间j位置的和刚好为sum[i]-k,那么从j+1到i的值就是k,符合情况。

3、i位置为k,那[0,i-1]就是sum[i]-k;

c7cab973aca34d9c8b66d399055d4e21.png

代码实现

class Solution { public: int subarraySum(vector<int>& nums, int k) { unordered_map<int,int> hash; hash[0]=1; int sum=0,ret=0; for(auto &x:nums) { sum+=x; if(hash.count(sum-k)) ret+=hash[sum-k]; hash[sum]++; } return ret; } };

 

 

这篇关于前缀和+哈希表:联手合击Leetcode 560.和为k的子数组的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/782179

相关文章

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

JavaScript对象转数组的三种方法实现

《JavaScript对象转数组的三种方法实现》本文介绍了在JavaScript中将对象转换为数组的三种实用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录方法1:使用Object.keys()和Array.map()方法2:使用Object.entr

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

Java中数组与栈和堆之间的关系说明

《Java中数组与栈和堆之间的关系说明》文章讲解了Java数组的初始化方式、内存存储机制、引用传递特性及遍历、排序、拷贝技巧,强调引用数据类型方法调用时形参可能修改实参,但需注意引用指向单一对象的特性... 目录Java中数组与栈和堆的关系遍历数组接下来是一些编程小技巧总结Java中数组与栈和堆的关系关于

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

MySQL JSON 查询中的对象与数组技巧及查询示例

《MySQLJSON查询中的对象与数组技巧及查询示例》MySQL中JSON对象和JSON数组查询的详细介绍及带有WHERE条件的查询示例,本文给大家介绍的非常详细,mysqljson查询示例相关知... 目录jsON 对象查询1. JSON_CONTAINS2. JSON_EXTRACT3. JSON_TA

JAVA数组中五种常见排序方法整理汇总

《JAVA数组中五种常见排序方法整理汇总》本文给大家分享五种常用的Java数组排序方法整理,每种方法结合示例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录前言:法一:Arrays.sort()法二:冒泡排序法三:选择排序法四:反转排序法五:直接插入排序前言:几种常用的Java数组排序

Java如何将文件内容转换为MD5哈希值

《Java如何将文件内容转换为MD5哈希值》:本文主要介绍Java如何将文件内容转换为MD5哈希值的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java文件内容转换为MD5哈希值一个完整的Java示例代码代码解释注意事项总结Java文件内容转换为MD5