leetcode分类刷题:哈希表(Hash Table)(四、前缀和 处理连续子数组)

1、leetcode题目里对于元素加和的考察可谓是屡见不鲜,包括 简单的限定一个有效答案的两个或多个元素求和leetcode分类刷题:哈希表(Hash Table)(一、简单的两数之和)、在有序数组内对加和等于target的三元组、四元组等的求解leetcode分类刷题:基于数组的双指针(三、有序数组的元素求和)以及连续子数组加和leetcode分类刷题:滑动窗口(一、基本子数组类型)
2、本文总结的题型同样为对连续子数组加和进行考察,区别于leetcode分类刷题:滑动窗口(一、基本子数组类型)的是,数组元素为整数,不是正整数了,因此需要按照 前缀和(按照闭区间形式,当前索引位置的值也算进去好理解)+哈希表 的思路进行解决,最后会发现这种题型就是leetcode分类刷题:哈希表(Hash Table)(一、简单的两数之和)的扩展,在解题模板上会有点类似

724. 寻找数组的中心下标

1、该题为典型的使用前缀和算法解决的问题,只需要两次遍历即可:第一次遍历求数组的和;第二次遍历求数组的前缀和,并判断对应位置是否为 中心下标
2、和1991. 找到数组的中间位置是完全一样的题目

from typing import List
'''
724. 寻找数组的中心下标
题目描述:给你一个整数数组nums ,请计算数组的 中心下标 。
数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。
如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。
如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。
示例 1:输入:nums = [1, 7, 3, 6, 5, 6]输出:3解释:中心下标是 3 。左侧数之和 sum = nums[0] + nums[1] + nums[2] = 1 + 7 + 3 = 11 ,右侧数之和 sum = nums[4] + nums[5] = 5 + 6 = 11 ,二者相等。
题眼:左侧右侧数组的和
思路1、三次遍历:第一次遍历建立从左到右的加和数组,第二次遍历建立从右到左的加和数组,第三次遍历对加和数组的对应位置判断相等情况
思路2、前缀和(按照闭区间形式,当前索引位置的值也算进去好理解):第一次遍历:求数组的和;第二次遍历:求数组的前缀和,并判断对应位置是否为 中心下标
'''class Solution:def pivotIndex(self, nums: List[int]) -> int:# 思路1、三次遍历# leftSum = [0] * len(nums)# s = 0# for i in range(len(nums)):#     s += nums[i]#     leftSum[i] = s# rightSum = [0] * len(nums)# s = 0# for i in range(len(nums) - 1, -1, -1):#     s += nums[i]#     rightSum[i] = s# for i in range(len(leftSum)):#     if leftSum[i] == rightSum[i]:#         return i# return -1# 思路2、前缀和# 第一次遍历:求数组的和total = 0for n in nums:total += n# 第二次遍历:求数组的前缀和,并判断对应位置是否为 中心下标prefixSum = 0for i in range(len(nums)):prefixSum += nums[i]if prefixSum * 2 - nums[i] == total:  # 这个条件的判断没有想到!!return ireturn -1if __name__ == "__main__":obj = Solution()while True:try:in_line = input().strip().split('=')nums = [int(n) for n in in_line[1].split('[')[1].split(']')[0].split(',')]print(obj.pivotIndex(nums))except EOFError:break

560. 和为 K 的子数组

1、通过题眼连续子数组来判断,该题很像是滑动窗口的解法,但数组元素为整数,不是正整数,不满足滑窗右边界增大元素之和递增、左指针增大元素之和递减
2、要用前缀和(按照闭区间形式,当前索引位置的值也算进去好理解)+哈希表的思路!
3、通过这道题也认识到,如果“1. 两数之和”不是限定了样例只存在一个答案,其哈希表更新的逻辑有缺陷

from typing import List
'''
560. 和为 K 的子数组
题目描述:给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的连续子数组的个数 。
示例 1:输入:nums = [1,1,1], k = 2输出:2
题眼:连续子数组,很像是滑动窗口的解法,但数组元素为整数,不是正整数,不满足滑窗右边界增大元素之和递增、左指针增大元素之和递减 了
思路:无法用滑动窗口了;要用前缀和(按照闭区间形式,当前索引位置的值也算进去好理解)+哈希表的思路!
“1. 两数之和”的扩展:通过这道题也认识到,如果“1. 两数之和”不是限定了样例只存在一个答案,其哈希表更新的逻辑有缺陷
'''class Solution:def subarraySum(self, nums: List[int], k: int) -> int:result = 0hashTable = {0: 1}  # 这里保证了对 包含起始元素的连续子数组 的判断prefixSum = 0for n in nums:  # 查找 以当前遍历元素n对应的索引位置为 右边界的连续子数组prefixSum += n   # 前缀和(按照闭区间形式,当前索引位置的值也算进去好理解)# 1、先找 以当前遍历元素n对应的索引位置 之前的前缀和是否存在满足条件的if prefixSum - k in hashTable:result += hashTable[prefixSum - k]# 2、再将当前遍历元素n对应的索引位置 的前缀和添加到hashDictif prefixSum not in hashTable:hashTable[prefixSum] = 1else:hashTable[prefixSum] += 1return resultif __name__ == "__main__":obj = Solution()while True:try:in_line = input().strip().split('=')nums = [int(n) for n in in_line[1].split('[')[1].split(']')[0].split(',')]k = int(in_line[2].strip())print(obj.subarraySum(nums, k))except EOFError:break

974. 和可被 K 整除的子数组

1、“560. 和为 K 的子数组”的衍生题,思路为完全一致的前缀和(按照闭区间形式,当前索引位置的值也算进去好理解)+哈希表
2、这道题比较难想的是使用 同余定理:两个除以k余数相等的数字,其差一定可以整除k,即 (preSumJ - preSumI)%K = 0 等价于 preSumJ%K == preSumI%K

from typing import List
'''
974. 和可被 K 整除的子数组
题目描述:给定一个整数数组 nums 和一个整数 k ,返回其中元素之和可被 k 整除的(连续、非空) 子数组 的数目。
子数组 是数组的 连续 部分。
示例 1:输入:nums = [4,5,0,-2,-3,1], k = 5  输出:7解释:有 7 个子数组满足其元素之和可被 k = 5 整除:  [4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]
题眼:连续子数组;“560. 和为 K 的子数组”的衍生题
思路:要用前缀和(按照闭区间形式,当前索引位置的值也算进去好理解)+哈希表的思路
同时,需要使用 同余定理 (preSumJ - preSumI)%K = 0 等价于 preSumJ%K == preSumI%K
'''class Solution:def subarraysDivByK(self, nums: List[int], k: int) -> int:# 需要用到 同余定理,两个除以k余数相等的数字,其差一定可以整除kresult = 0hashTable = {0: 1}  # 这里保证了对 包含起始元素的连续子数组 的判断prefixSum = 0for n in nums:  # 查找 以当前遍历元素n对应索引位置为边界的连续子数组prefixSum += n  # 前缀和(按照闭区间形式,当前索引位置的值也算进去好理解)if prefixSum % k in hashTable:result += hashTable[prefixSum % k]hashTable[prefixSum % k] += 1else:hashTable[prefixSum % k] = 1return resultif __name__ == "__main__":obj = Solution()while True:try:in_line = input().strip().split('=')nums = [int(n) for n in in_line[1].split('[')[1].split(']')[0].split(',')]k = int(in_line[2].strip())print(obj.subarraysDivByK(nums, k))except EOFError:break

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/68999.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【链表OJ 11】复制带随机指针的链表

前言: 💥🎈个人主页:​​​​​​Dream_Chaser~ 🎈💥 ✨✨刷题专栏:http://t.csdn.cn/UlvTc ⛳⛳本篇内容:力扣上链表OJ题目 目录 leetcode138. 复制带随机指针的链表 1. 问题描述 2.代码思路: 2.1拷贝节点插入到…

【文心一言大模型插件制作初体验】制作面试错题本大模型插件

文心一言插件开发初体验 效果图 注意:目前插件仅支持在本地运行,虽然只能自用,但仍然是一个不错的选择。(什么?你说没有用?这不可能!文心一言app可以支持语音,网页端结合手机端就可…

Android Studio设置

Android Studio设置 一、主题 1.下载插件并重启 Material Theme UI 2.下载插件ChroMATERIAL 3.设置主题File >> Settings >> Editor >> Colors Scheme >> Scheme >> ChroMATERIAL 4.设置logcat色值File → Settings → Editor → Colors Schem…

计算机网络第三节物理层

一,第二章 物理层(数据通信有关) 1.物理层引入的目的 屏蔽掉传输介质的多样性,导致数据传输方式的不同;物理层的引入使得高层看到的数据都是统一的0,1构成的比特流 2.物理层如何实现屏蔽 物理层靠定义的不同的通信…

12 | 使用 Spark SQL执行CURL

Spark SQL 是 Apache Spark 生态系统中的一个组件,它提供了用于结构化数据处理和分析的高级接口。Spark SQL 可以让用户使用 SQL 语言来查询和操作数据,同时也提供了强大的分布式计算能力。下面是关于 Spark SQL、SparkSession 和 DataFrame 的关键点: 1. Spark SQL: 定义…

智慧园区用水用电信息管理系统:实现高效节能的现代化园区管理

随着科技的不断发展,各类产业园区在我国经济社会发展中发挥着越来越重要的作用。为了提高园区的运营效率、降低能源消耗、实现绿色可持续发展,智慧园区用水用电信息管理系统应运而生。本文将从系统背景、功能特点、应用优势等方面进行详细介绍。 一、系统…

【Linux】进程间通信与同步

IPC进程间通信 无名管道pipe(血缘关系的进程)有名管道fifo (无血缘关系的进程)共享内存信号(开销小)消息队列信号量套接字 进程间同步 文件锁信号量

java八股文面试[数据库]——索引下推

什么是索引下推? 索引下推(index condition pushdown )简称ICP,在Mysql5.6的版本上推出,用于优化查询。 需求: 查询users表中 "名字第一个字是张,年龄为10岁的所有记录"。 SELECT * FROM users…

element+vue table表格全部数据和已选数据联动

1.组件TableChoose <template><div class"tableChooseBox"><div class"tableRow"><div class"tableCard"><div class"tableHeadTip">全部{{ labelTitle }}</div><slot name"body" …

Jupyter Notebook 好用在哪?

Jupyter Notebook 是一个 Web 应用程序&#xff0c;便于创建和共享文学化程序文档&#xff0c;支持实时代码、数学方程、可视化和 Markdown&#xff0c;其用途包括数据清理和转换、数值模拟、统计建模、机器学习等等。目前&#xff0c;数据挖掘领域中最热门的比赛 Kaggle 里的资…

MySQL用navicat工具对表进行筛选查找

这个操作其实很简单&#xff0c;但是对于没操作的人来说&#xff0c;就是不会呀。所以小编出这一个详细图解&#xff0c;希望能够帮助到大家。话不多说看图。 第一步&#xff1a; 点进一张表&#xff0c;点击筛选。 第二步&#xff1a; 点击添加 第三步&#xff1a; 选择要…

诗诺克科技引领数字资产智能交易革命

在当今全球金融市场中&#xff0c;数字资产的崛起正引发着一场前所未有的变革。随着区块链技术不断演进和数字资产广泛获得认可&#xff0c;智能交易系统正在迅速成为投资者和交易者的首选工具。这一趋势不仅在全球范围内显著&#xff0c;而且为金融领域的未来带来了令人瞩目的…

前端、后端面试集锦

诸位读者&#xff0c;我们在工作的过程中&#xff0c;经常会因跳槽而面试。 你开发能力很强&#xff0c;懂得技术也很多&#xff0c;若加上条理清晰的面试话术&#xff0c;可以让您的面试事半功倍。 个人博客阅读量破170万&#xff0c;为尔倾心打造的 面试专栏-前端、后端面试…

【ES6】fetch函数和Promise

fetch函数是现代JavaScript中用于发起HTTP请求的一个非常强大的工具。它返回一个Promise&#xff0c;这个Promise在请求成功时解析为Response对象&#xff0c;或者在请求失败时拒绝。 以下是一个基本的fetch使用示例&#xff1a; fetch(https://api.example.com/data).then(r…

总结开发中一些数据处理方法的封装

摘要&#xff1a; 开发中经常会遇到一些组件需要的特定数据结构&#xff0c;后端不一定会返回你需要的数据结构的&#xff0c;所以还是要前端来处理的&#xff01;这里来总结一下平常开发中遇到的需要处理结构的方法&#xff0c;下次遇到直接拿来用就可以了&#xff01; 目录概…

mac苹果电脑删除顽固残留软件图标

核心&#xff1a;删除“启动台”数据库里对应app的信息 1、打开访达&#xff08;Finder&#xff09;&#xff0c;点击最顶部菜单栏的【前往》前往文件夹】&#xff0c;接着输入【/private/var/folders】 2、在弹出的访达&#xff08;Finder&#xff09;窗口搜索栏输入【com.ap…

Docker构建Springboot项目,并发布测试

把SpringBoot项目打包成Docker镜像有两种方案&#xff1a; 全自动化&#xff1a;先打好docker镜像仓库&#xff0c;然后在项目的maven配置中配置好仓库的地址&#xff0c;在项目里配置好Dockerfile文件&#xff0c;这样可以直接在idea中打包好后自动上传到镜像仓库&#xff0c…

使用C++实现图片的快速的无损压缩和解压缩

1.实现原理 实现完整的图片无损压缩和解压缩需要使用一些图像处理库,例如OpenCV,libjpeg,libpng,等等。这里我们以libjpeg为例进行介绍。 2.压缩函数 压缩:首先需要读取图片,将其转换成JPEG格式,然后进行压缩。 #include <stdio.h> #include <jpeglib.h>v…

抢跑预制菜,双汇发展转守为攻?

懒&#xff0c;懒出新风口&#xff0c;预制菜竟成了年轻人新时代的“田螺神话”&#xff1f; 《2022年中国预制菜产业发展白皮书》数据显示&#xff0c;2022年全国预制菜的市场规模是4196亿元人民币&#xff0c;到2026年可以突破万亿大关。 预制菜的火爆显而易见&#xff0c;…

使用docker容器内的anaconda虚拟环境启动python web项目

1、环境安装 1.1 基础镜像 这里以ubuntu18.04 cuda 11.8为基础镜像&#xff08;主机支持nvidia-gpu&#xff09; &#xff08;1&#xff09;拉取ubuntu18.4 cuda11.8镜像 docker pull nvidia/cuda:11.8.0-devel-ubuntu18.04 1.2 docker下anaconda安装 &#xff08;1&am…