当前位置: 首页 > wzjs >正文

佛山新网站建设特色seo推广培训

佛山新网站建设特色,seo推广培训,承德建设网站,花都营销型网站建设描述 在由若干 0 和 1 组成的数组 A 中,有多少个和为 S 的非空子数组 样例 1: 输入:A [1,0,1,0,1], S 2 输出:4 解释: 如下面黑体所示,有 4 个满足题目要求的子数组: [1,0,1] [1,0,1] [1,0,1,0] [0,1,…

描述

在由若干 0 和 1 组成的数组 A 中,有多少个和为 S 的非空子数组

样例 1:

输入:A = [1,0,1,0,1], S = 2
输出:4
解释:
如下面黑体所示,有 4 个满足题目要求的子数组:
[1,0,1]
[1,0,1]
[1,0,1,0]
[0,1,0,1]

样例 2:

输入:A = [0,0,0,0,0,0,1,0,0,0], S = 0
输出:27
解释:
和为 S 的子数组有 27 个

思路1 采用同向双指针法 通过暴力双指针枚举所有起点 + 滑动右指针

每轮固定左指针 left,右指针从 left 向右滑动; 每次累加和,如果等于 S,就记录这个子数组; 关键点是从每个 left 出发,向右滑,不能随便跳过任何一个组合

代码1:

public class Solution {

    public int numSubarraysWithSum(int[] A, int S) {

        int n=A.length;

        int count=0;

        for(int left = 0; left < n; left++)//同向双指针法计算是否为目前值S

        {

            int accumulatedNum = 0;

            for (int right = left; right < n; right++) {

                accumulatedNum += A[right];

                if (accumulatedNum == S) {

                    count++;

                } else if (accumulatedNum > S) {

                    break; // 再滑动右指针没意义了

                }

            }

           

        }

        return count;

    }

}

思路2 前缀和 + 哈希表

每轮固定左指针 left,右指针从 left 向右滑动; 每次累加和,如果等于 S,就记录这个子数组; 关键点是从每个 left 出发,向右滑,不能随便跳过任何一个组合

任意一个子数组 [i..j] 的和 = prefixSum[j] - prefixSum[i-1] 若要求 sum[i..j] = S,则等价于: prefixSum[j] - prefixSum[i-1] == S → prefixSum[i-1] == prefixSum[j] - S

prefixMap 来记录前缀和出现的次数,作用是:

键(Key)值(Value)
某个前缀和 x这个前缀和 x 出现过多少次

prefixMap.put(0, 1); 

前缀和为 0 出现了 1 次(这是初始化)

它允许我们从下标 0 开始的子数组也能被统计进来

accumulatedNum 当前前缀和,也就是从 A[0] 到 A[i] 的累加值

count 当前找到的子数组个数,最终返回这个值

步骤 1:累加前缀和 

accumulatedNum += A[i]; // 累加前缀和 将当前元素 A[i] 累加到 accumulatedNum 中; accumulatedNum 代表前缀和 prefixSum[i]

每次比较都是当前前缀和-s 当有

既等式

prefixSum[j] - prefixSum[i-1] == S
prefixSum[i-1] == prefixSum[j] - S
accumulatedNum - S

是我们想找的值 意思为在前面的位置出现过这样一个前缀和,
这样从那个位置之后到我当前位置,就刚好是一个和为 S 的子数组

prefixMap.get(accumulatedNum - S)之前有多少个位置,它们的前缀和等于 accumulatedNum - S

每一个都可以作为「合法子数组的起点」,从那个点到当前 i 的子数组和为 S
所以:prefixMap.get(accumulatedNum - S) 就是当前命中的合法子数组个数

prefixMap.put(accumulatedNum, prefixMap.getOrDefault(accumulatedNum, 0) + 1);
把当前的前缀和 accumulatedNum 的出现次数 +1

因为我们要统计「从前面某个位置 i 到当前位置 j 的和为 S 的子数组数量」。

每一个前缀和,都可能为后面提供组合,所以我们必须记录它出现的次数

import java.util.*;

public class Solution {
    public int numSubarraysWithSum(int[] A, int S) {
        int accumulatedNum = 0; // 当前的前缀和
        int count = 0;

        Map<Integer, Integer> prefixMap = new HashMap<>();
        prefixMap.put(0, 1); // 初始化:前缀和为 0 出现了 1 次

        for (int i = 0; i < A.length; i++) {
            accumulatedNum += A[i]; // 累加当前前缀和

            // 如果之前出现过 accumulatedNum - S,就说明找到了满足条件的子数组
            if (prefixMap.containsKey(accumulatedNum - S)) {
                count += prefixMap.get(accumulatedNum - S);
            }

            // 更新当前前缀和出现次数
            prefixMap.put(accumulatedNum, prefixMap.getOrDefault(accumulatedNum, 0) + 1);
        }

        return count;
    }
}   

一个疑问点是如果不写

那么就会漏掉那些从 index = 0 开始就满足和为 S 的子数组

例 A = [1, 0, 1], S = 2

有 prefixMap.put(0, 1) 的时候:

iA[i]accumulatedNumaccumulatedNum - SprefixMap命中count
011-10
101-10
21201

最终结果: 找到了子数组 [0, 1, 2],和为 2。

当prefixMap.put(0, 1)没有的时候 

当前累计为 2 的时候,你想找的前缀和是 0,但 prefixMap 里没有

prefixMap.getOrDefault(accumulatedNum, 0) 会取下标为0的值 因为没有放入1 则

这段合法子数组 [1, 0, 1] 就不会被统计 即错误结果 最终结果是:count=0

推荐刚开始学习使用双指针法 进阶使用前缀和 + 哈希表

http://www.dtcms.com/wzjs/26023.html

相关文章:

  • 建网站 免费网站功能
  • 阅读网站怎么做个人网站源码免费下载
  • 网址怎么输入英文seo是什么意思
  • 做时时彩网站要多少钱网页平台做个业务推广
  • 周口哪家做网站好电工培训机构
  • 中国有兼职网站开发网站吗深圳推广平台有哪些
  • 网站建设注意细节问题seo技术蜘蛛屯
  • 徐州网站建设公司推广策划方案范文
  • 自建域名seo是什么意思中文翻译
  • 家具网站建设目的及功能定位网站生成app
  • 外置硬盘可以做网站访问十大app开发公司排名
  • 类似链家网站建设方案软文营销软文推广
  • 大气装饰公司网站源码汕头seo优化项目
  • 新建网站外链怎么做江阴百度推广公司
  • 智慧团建网站登录密码是啥企业网站建设方案模板
  • 梁平网站建设网站怎么做外链
  • 天津市建设厅政府网站烟台seo快速排名
  • 做国外网站建设搜索热词排行榜
  • 安徽做手机网站网站排名优化技巧
  • 建设项目环保竣工信息公开网站seo网站有优化培训吗
  • 网站建设在哪块做买卖交易网
  • 网站开发域名品牌整合营销方案
  • 网站程序模板下载学推广网络营销去哪里
  • 网站预订功能怎么做微商如何引流与推广
  • 潍坊做网站价格app如何推广以及推广渠道
  • 商城网站建设制作设计电话营销系统
  • 如何看一个网站做的如何网店代运营十大排名
  • 微信做网站其他搜索引擎
  • html转换wordpress志鸿优化设计答案网
  • 高邮做网站群排名优化软件