day4_prefixSum2

2024-05-15 14:36
文章标签 day4 prefixsum2

本文主要是介绍day4_prefixSum2,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

参考链接【强化练习】前缀和技巧经典习题 | labuladong 的算法笔记

一、前缀和技巧经典习题

1.523连续的子数组和
class Solution {public boolean checkSubarraySum(int[] nums, int k) {int n = nums.length;// 计算 nums 的前缀和int[] preSum = new int[n + 1];preSum[0] = 0;for (int i = 1; i <= n; i++) {preSum[i] = preSum[i - 1] + nums[i - 1];}// 前缀和与 k 的余数到索引的映射,方便快速查找所需的前缀和HashMap<Integer, Integer> valToIndex = new HashMap<>();for (int i = 0; i < preSum.length; i++) {// 在哈希表中记录余数int val = preSum[i] % k;// 如果这个余数还没有对应的索引,则记录下来if (!valToIndex.containsKey(val)) {valToIndex.put(val, i);}// 如果这个前缀和已经有对应的索引了,则什么都不做// 因为题目想找长度最大的子数组,所以前缀和索引应尽可能小}int res = 0;for (int i = 1; i < preSum.length; i++) {// 计算 need,使得 (preSum[i] - need) % k == 0int need = preSum[i] % k;if (valToIndex.containsKey(need)) {//获得的need(余数)对应的索引,如果索引相减 > 2,表示长度 > 2 满足条件if (i - valToIndex.get(need) >= 2) {// 这个子数组的长度至少为 2return true;}}}return false;}
}
2.连续数组

该题使用了技巧,将0和1出现次数相等的条件(子数组相加结果多种可能),改变成相加为0(如果出现0,就向前缀和数组中加上-1),使得该题可以用前缀和数组解决

class Solution {public int findMaxLength(int[] nums) {int n = nums.length;int[] preSum = new int[n + 1];preSum[0] = 0;// 计算 nums 的前缀和for (int i = 0; i < n; i++) {//技巧preSum[i + 1] = preSum[i] + (nums[i] == 0 ? -1 : 1);}// 前缀和到索引的映射,方便快速查找所需的前缀和HashMap<Integer, Integer> valToIndex = new HashMap<>();int res = 0;for (int i = 0; i < preSum.length; i++) {// 如果这个前缀和还没有对应的索引,说明这个前缀和第一次出现,记录下来if (!valToIndex.containsKey(preSum[i])) {valToIndex.put(preSum[i], i);} else {// 这个前缀和已经出现过了,则找到一个和为 0 的子数组res = Math.max(res, i - valToIndex.get(preSum[i]));}// 因为题目想找长度最大的子数组,所以前缀和索引应尽可能小}return res;}
}
3.和为k的子数组

这道题其实在考察 前缀和技巧 和哈希表的结合使用,请你先解决 523. 连续的子数组和 和 525. 连续数组,然后这道题就很容易解决了。

本题和前两题的最大区别在于,需要在维护 preSum 前缀和数组的同时动态维护 count 映射,而不能等到 preSum 计算完成后再处理 count,因为 count[need] 应该维护 preSum[0..i] 中值为 need 的元素个数。

怎么理解 因为 count[need] 应该维护 preSum[0..i] 中值为 need 的元素个数 这句话,

举个例子,数组[0,end]索引中有 a,b,c,对应的值为v1,某个索引x值为v2,它们的大小关系是 a<b<x<c<end,且(v2 - v1)== k,当遍历到x时满足条件的子数组数量为2(preSum[x+1] - preSum[a+1] 和 preSum[x+1] - preSum[b+1]),c并不满足这个条件,所以要在计算preSum[n+1]数组的过程计算count[need]的数量,而不是在计算完preSum之后再计算,会浪费时间

class Solution {public int subarraySum(int[] nums, int k) {int n = nums.length;// 前缀和数组int[] preSum = new int[n + 1];preSum[0] = 0;// 前缀和到该前缀和出现次数的映射,方便快速查找所需的前缀和HashMap<Integer, Integer> count = new HashMap<>();
//如果某个索引的前缀和刚好等于 k,那么 need = 0,res += count.get(need); 就不会报错count.put(0, 1);// 记录和为 k 的子数组个数int res = 0;// 计算 nums 的前缀和for (int i = 1; i <= n; i++) {preSum[i] = preSum[i - 1] + nums[i - 1];// 如果之前存在值为 need 的前缀和// 说明存在以 nums[i-1] 结尾的子数组的和为 kint need = preSum[i] - k;if (count.containsKey(need)) {res += count.get(need);}// 将当前前缀和存入哈希表if (!count.containsKey(preSum[i])) {count.put(preSum[i], 1);} else {count.put(preSum[i], count.get(preSum[i]) + 1);}}return res;}
}
4. 238.除自身以外数组的乘积

(前缀 “积”) 使用前缀积 乘以 后缀积,获得当前res[i]的值

class Solution {public int[] productExceptSelf(int[] nums) {int n = nums.length;// 从左到右的前缀积,prefix[i] 是 nums[0..i] 的元素积int[] prefix = new int[n];prefix[0] = nums[0];for (int i = 1; i < nums.length; i++) {prefix[i] = prefix[i - 1] * nums[i];}// 从右到左的前缀积,suffix[i] 是 nums[i..n-1] 的元素积int[] suffix = new int[n];suffix[n - 1] = nums[n - 1];for (int i = n - 2; i >= 0; i--) {suffix[i] = suffix[i + 1] * nums[i];}// 结果数组int[] res = new int[n];res[0] = suffix[1]; res[n - 1] = prefix[n - 2];for (int i = 1; i < n - 1; i++) {// 除了 nums[i] 自己的元素积就是 nums[i] 左侧和右侧所有元素之积res[i] = prefix[i - 1] * suffix[i + 1];}return res;}
}

这篇关于day4_prefixSum2的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

算法训练营——day4螺旋矩阵

1 螺旋矩阵II-力扣59(中等) 1.1 题目:螺旋矩阵II 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1: 输入:n = 3输出:[[1,2,3],[8,9,4],[7,6,5]] 示例 2: 输入:n = 1输出:[[1]] 提示: 1 <= n <= 20 1.

Android智能家居实训day4

今天进行了服务器的部署,和服务器的连接,以及进行了代码整合 再进行学习之前又对线程的知识进行了回顾因为进行连接服务器的时候要通过子线程来进行,线程的启动使用start函数,如果使用run函数相当于执行了一个函数而不是新创建一个子线程。 服务器的部署并没有深究,只是把服务器代码的压缩包放到了虚拟机上。 连接的时候首先要给AndroidManifest.xml文件添加网络权限,其次就是把防火墙关掉。

urfread刷算法题day4|27. 移除元素+复习

27. 移除元素 题目描述 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作:更改 nums 数组,使 nums 的前 k 个元素包含不等于 val 的元素。nums 的其余元素和 nums

【进阶篇-Day4:使用JAVA编写石头迷阵游戏】

目录 1、绘制界面2、打乱石头方块3、移动业务4、游戏判定胜利5、统计步数6、重新游戏7、完整代码: 1、绘制界面 上述思路是:使用一个二维数组存放图片的编号,然后在后持遍历即可获取对应的图片。 代码如下: package com.itheima.stonepuzzle;import javax.swing.*;public cla

华为实习day4

今天开始真正的研究工作,内容当然是我大前端。工作大致是下面这些, 1.学习使用华为办公软件和学习平台(espace,3ms等) 2.学习JavaScript和Jquery(阅读JavaScript权威指南和锋利的Jquery两本书),粗略的看完JavaScript这本书,明白了JavaScript的基本知识,会运用JavaScript做一些简单的页面。 3.仿照书上的例子自己实现了一

计算机网络学习记录 网络层 Day4(下)

计算机网络学习记录 网络层 Day4 (下) 你好,我是Qiuner. 为记录自己编程学习过程和帮助别人少走弯路而写博客 这是我的 github https://github.com/Qiuner ⭐️ ​ gitee https://gitee.com/Qiuner 🌹 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 😄 (^ ~ ^) 想看更多 那就点个关注吧 我会尽力带来有趣的内

day4 数1 隐函数

基础知识 隐函数 :一个方程里边 使x有1个y与之对应 函数的有界性 f(X) 的值大于-M并小于M 单调性 可以用定义发判断单调性 定义法 奇函数 奇函数关于原点对称,偶关于x对称 定义域要关于原点对称 任何一个函数可以写成奇函数+偶函数的形式 复合函数的奇偶 函数和它导数的奇偶性相反 当下限为a时,偶函数的积分未必为奇,要考虑常数C

算法题day37日(补5.23日卡:贪心算法day4)

一、刷题: 1.leetcode题目 860. 柠檬水找零 - 力扣(LeetCode)(easy): 我觉得我写的代码有点蠢 class Solution:def lemonadeChange(self, bills: List[int]) -> bool:dict_ = {5:0,10:0}if bills[0] != 5:return Falsefor i in bills:if i

【WEEK14】 【DAY4】Swagger Part 2【English Version】

2024.5.30 Thursday Following up on 【WEEK14】 【DAY3】Swagger Part 1【English Version】 Contents 16.4. Configure Scanned Interfaces16.4.1. Modify SwaggerConfig.java16.4.1.1. Use the .basePackage() Metho