LeetCode算法实践——前缀和从入门到入土

前缀和算法

对于一个数组a,和为s数组;其每一个下标的前缀和为s[0]=0,s[i]=s[i-1]+a[i]。

从上面可以推导出left到right之间的前缀和为是s[right+1]-s[left]。

例如a=[3,2,1,2],对应的前缀和数组为s=[0,3,5,6,8]。a的子数组[2,1,2]的和就可以用s[4]−s[1]=8−3=5算出来。
在这里插入图片描述

算法实践

LeetCode 930. 和相同的二元子数组

给你一个二元数组nums,和一个整数goal,请你统计并返回有多少个和为goal的非空子数组。

解题思路

定义前缀和数组sum,如果i…j之间和为goal,那么有sum[j]-sum[i]=goal。因此可以枚举j即可。实际解题时可以用哈希记录每一种前缀和出现的次数。

class Solution {
    public int numSubarraysWithSum(int[] nums, int goal) {
        if (nums==null || nums.length==0){
            return 0;
        }
        int sum=0;
        HashMap<Integer,Integer>cnt=new HashMap<>();
        int res=0;
        for(int num:nums){
            cnt.put(sum,cnt.getOrDefault(sum,0)+1);
            sum+=num;
            res+=cnt.getOrDefault(sum-goal,0);
        }

        return res;

    }
}

LeetCode 560. 和为 K 的子数组

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

解题思路

跟930题一致。

LeetCode 524. 和为奇数的子数组数目

给你一个整数数组arr。请你返回和为奇数的子数组数目。

由于答案可能会很大,请你将结果对10^9+7取余后返回。

解题思路

求子数组和可以通过前缀和的方式,本题中只需要维护奇数和偶数的数量,不需要维护前缀和数组。

class Solution {
    public int numOfSubarrays(int[] arr) {
        final int MODULO = 1000000007;
        int odd = 0, even = 1;
        int subarrays = 0;
        int sum = 0;
        int length = arr.length;
        for (int i = 0; i < length; i++) {
            sum += arr[i];
            subarrays = (subarrays + (sum % 2 == 0 ? odd : even)) % MODULO;
            if (sum % 2 == 0) {
                even++;
            } else {
                odd++;
            }
        }
        return subarrays;
    }
}

LeetCode 面试题 17.05. 字母与数字

给定一个放有字母和数字的数组,找到最长的子数组,且包含的字母和数字的个数相同。

返回该子数组,若存在多个最长子数组,返回左端点下标值最小的子数组。若不存在这样的数组,返回一个空数组。

解题思路

一个子数组包含的字母和数字的个数相同,等价于该子数组包含的字母和数字的个数之差为0,可以将字母转为-1,数字转为1。问题等价于在转换后的数组中寻找元素和为0的最长子数组。

为了在转换后的数组中寻找元素和为0的子数组,可以计算转换后的数组的前缀和,如果两个下标对应的前缀和相等,则这两个下标之间的子数组的元素和为0。

使用哈希表记录每个前缀和第一次出现的下标。由于空前缀的前缀和是0且对应下标-1,因此首先将前缀和0与下标-1存入哈希表。

class Solution {
    public String[] findLongestSubarray(String[] array) {
        HashMap<Integer,Integer>map=new HashMap<>();
        map.put(0,-1);
        int sum=0;
        int maxLen=0;
        int startIndex=-1;
        int len=array.length;
        for(int i=0;i<len;i++){
            if (Character.isLetter(array[i].charAt(0))){
                sum++;
            }else{
                sum--;
            }
            if (map.containsKey(sum)){
                int index=map.get(sum);
                if (i-index>maxLen){
                    maxLen=i-index;
                    startIndex=index+1;
                }
            }else{
                map.put(sum,i);
            }
        }    
        if (maxLen == 0) {
            return new String[0];
        }
        String[] ans = new String[maxLen];
        System.arraycopy(array, startIndex, ans, 0, maxLen);
        return ans; 
    }
}

总结

前缀和技术主要用于高效地计算数组的区间和,在需要快速求解子数组或子序列的问题中非常有用。以下是前缀和的一些典型应用场景:

  • 求解区间和:通过前缀和,我们可以在常数时间内计算出数组任何区间[l, r]的和,计算公式为 S[r] - S[l-1],其中 S[] 是前缀和数组。

  • 统计问题:前缀和可以用于解决一些统计问题,如计算数组中正数和负数的数量,或者统计某个元素出现的次数等。

  • 坐标缩放问题:在处理坐标系相关的问题时,前缀和技术可以用来计算新的坐标值,例如在坐标缩放问题中,可以通过前缀和技术快速计算出每个点的新坐标。

  • 哈希表结合使用:在需要快速检索的场景中,前缀和技术经常与哈希表结合使用,以提高查询效率。

  • 动态规划:在一些动态规划问题中,前缀和技术可以用来优化状态转移方程,减少计算量。

综上所述,前缀和是一种非常实用的技术,其可以在各种需要快速求解子数组或子序列的场景中发挥作用,尤其在与哈希表结合使用时,能够显著提高算法的效率。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu22.04@laptop OpenCV Get Started: 015_deep_learning_with_opencv_dnn_module

ubuntu22.04laptop OpenCV Get Started: 015_deep_learning_with_opencv_dnn_module 1. 源由2. 应用Demo2.1 C应用Demo2.2 Python应用Demo 3. 使用 OpenCV DNN 模块进行图像分类3.1 导入模块并加载类名文本文件3.2 从磁盘加载预训练 DenseNet121 模型3.3 读取图像并准备为模型输…

用pandas做简单策略回测

一&#xff0c;RSI策略 数据&#xff1a; 代码 import pandas as pd# 读取贵州茅台股票历史交易数据 df pd.read_csv(贵州茅台股票历史交易数据.csv) missing_values df.isnull().sum()# print("缺失值数量&#xff1a;") # print(missing_values)# 计算RSI指标 …

Windows 使设置更改立即生效——并行发送广播消息

目录 前言 1 遍历窗口句柄列表 2 使用 SendMessageTimeout 发送延时消息 3 并行发送消息实现模拟广播消息 4 修改 UIPI 消息过滤器设置 5 托盘图标刷新的处理 6 完整代码和测试 本文属于原创文章&#xff0c;转载请注明出处&#xff1a; https://blog.csdn.net/qq_5907…

PostgreSQL里实现计算多个数字的排列组合

在进行排列组合的时候&#xff0c;每一次需要知道是否有重复的值&#xff0c;并过滤出已经排列过的值。这个可以创建支持可变参数的函数来实现。下边的函数用到了聚合判断&#xff0c;并且可变参数使用variadic标记的数组。 postgres<16.1>(ConnAs[postgres]:PID[188277…

SICTF Round#3 wp web

web hacker sql无列名注入&#xff1b; 提示查询username参数&#xff0c;flag在flag表中&#xff1b; 传参测试发现&#xff0c;union select 可用&#xff0c;空格被过滤可以使用/**/代替 &#xff0c;or也被过滤了且无法大小写、双写等绕过&#xff0c;导致无法查询flag表…

在线SM3 HMAC加密工具

在线HMAC加密工具提供一站式服务&#xff0c;支持MD5至SHA512、RIPEMD160及SM3等多种哈希算法&#xff0c;用户可便捷选择算法并生成安全的HMAC散列值&#xff0c;确保消息完整性与验证来源。适用于开发调试、网络安全测试及敏感数据处理场景。 在线HMAC加密 - BTool在线工具软…

【VSCode编写JavaScript】

VSCode编写JavaScript ■ 下载安装VSCode■ VSCode统一配置■ 格式化工具■ Tab size &#xff08;代码缩进 2个字符&#xff09;![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/7b79c59636f147c8b08a0fff37886e0a.png) ■ VSCode安装JS插件■ VSCode新建JS工程代码…

性能测试概述

1.性能测试介绍 好处: 有效的性能测试能给研发、运维团队提供有效的容量规划能力、系统风险识别、系统瓶颈识别、性能调优指导,保障尽量避免这些问题的发生。 例如: 假设:以下场景,不可用10分钟,带来的经济损失 天猫双十一峰值处理订单58.3万笔每秒 京东金融618战报…

fastApi笔记01-路径参数

路径参数 使用与 Python 格式化字符串相同的语法来声明路径"参数"或"变量" from fastapi import FastAPIapp FastAPI()app.get("/items/{item_id}") def read_item(item_id):return {"item_id": item_id} http://127.0.0.1:8000/i…

看小姐姐的效果棒极了,写了一个工具,逐帧解析视频转成图片,有没有带上商业思维的小伙伴一起研究下

一个突然的想法&#xff0c;促成了这个项目雏形。 原理是&#xff1a; 上传一个视频&#xff0c;自动将视频每一帧保存成图片 然后前端访问 就能实现如图效果 后端是python/flask 数据库mysql 前端uniapp 项目演示&#xff1a; xt.iiar.cn 后端代码如下&#xff1a; #学习…

蓝桥杯嵌入式STM32G431RBT6知识点(主观题部分)

目录 1 前置准备 1.1 Keil 1.1.1 编译器版本及微库 1.1.2 添加官方提供的LCD及I2C文件 1.2 CubeMX 1.2.1 时钟树 1.2.2 其他 1.2.3 明确CubeMX路径&#xff0c;放置芯片包 2 GPIO 2.1 实验1&#xff1a;LED1-LED8循环亮灭 ​编辑 2.2 实验2&#xff1a…

解决Edge浏览器,微博无法查看大图(Edge Image Viewer)

使用Edge浏览器浏览微博或其它带校验的图片时&#xff0c;会导致无法查看。 主要原因为Edge自带了一个Edge Image Viewer, 但是该图片查看器无法查看带校验数据的图片&#xff0c;所以导致查看时一片空白。 解决方法 地址栏输入 edge://flags/搜索 Edge Image Viewer选择 Disa…

c# #if 与 Conditional属性宏的区别

测试代码 using System; using System.Diagnostics;namespace ConsoleApp1 {public class TestClass{[Conditional("Debug1")]public static void Func1(){Console.WriteLine("Conditional 宏");}public static void Func2(){ #if Debug2Console.WriteLin…

【lesson59】线程池问题解答和读者写者问题

文章目录 线程池问题解答什么是单例模式什么是设计模式单例模式的特点饿汉和懒汉模式的理解STL中的容器是否是线程安全的?智能指针是否是线程安全的&#xff1f;其他常见的各种锁 读者写者问题 线程池问题解答 什么是单例模式 单例模式是一种 “经典的, 常用的, 常考的” 设…

【MATLAB源码-第140期】基于matlab的深度学习的两用户NOMA-OFDM系统信道估计仿真,对比LS,MMSE,ML。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 深度学习技术在无线通信领域的应用越来越广泛&#xff0c;特别是在非正交多址接入&#xff08;NOMA&#xff09;和正交频分复用&#xff08;OFDM&#xff09;系统中&#xff0c;深度学习技术被用来提高信道估计的性能和效率。…

Jmeter实现阶梯式线程增加的压测

安装相应jmeter 插件 1&#xff1a;安装jmeter 管理插件&#xff1a; 下载地址&#xff1a;https://jmeter-plugins.org/install/Install/&#xff0c;将下载下来的jar包放到jmeter文件夹下的lib/ext路径下&#xff0c;然后重启jmeter。 2&#xff1a;接着打开 选项-Plugins Ma…

【力扣 - 二叉树的最大深度】

题目描述 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 提示&#xff1a; 树中节点的数量在 [0, 10^4] 区间内。 -100 < Node.val < 100方法一&#xff1a;深度优先搜索 思路与算法 如…

面试经典150题——矩阵置零

​"Dream it. Wish it. Do it." - Unknown 1. 题目描述 2. 题目分析与解析 2.1 思路一——暴力求解 思路一很简单&#xff0c;就是尝试遍历矩阵的所有元素&#xff0c;如果发现值等于0&#xff0c;就把当前行与当前列的值分别置为0。同时我们需要注意&#xff0c;…

5G车载路由器引领无人驾驶车联网应用

随着无人驾驶技术的不断发展&#xff0c;车联网正逐渐成为实现智能交通的重要组成部分。5G车载路由器将在车联网的应用中起到至关重要的作用&#xff0c;它能够满足无人驾驶应用的低时延、高速率和实时控制等需求&#xff0c;进一步推动无人驾驶车联网技术。 5G路由器具备低时延…

VUE3 中导入Visio 图形

微软的Visio是一个功能强大的图形设计工具&#xff0c;它能够绘制流程图&#xff0c;P&ID&#xff0c;UML 类图等工程设计中常用的图形。它要比其它图形设计软件要简单许多。以后我的博文中将更多地使用VISO 来绘制图形。之前我一直使用的是corelDraw。 Visio 已经在工程设…