JavaScript刷题——前缀和数组、差分数组

303.区域和检索 - 数组不可变

已知一维数组长度,创建数组:
const preSum = new Array(nums.length + 1);
而我是先赋值第一个元素,再push添加新元素:

this.arr = [nums[0]]

Javascript 数组下标
在这里插入图片描述
下标-1 并不是越界。

304.二维区域和检索 - 矩阵不可变
创建二维数组:

const preSum = new Array(rows+1)
for (let i = 0; i < rows; i++) {
	preSum[i] = new Array(cols+1)
}

行列+1,避免考虑越界问题
在这里插入图片描述
求子矩阵给出的坐标实际要+1。

560.和为 K 的子数组——(fail)
由于存在负数,不能使用双指针移动的方式
还是每个元素对应一个“前缀和”,当前“前缀和”与历史前缀和,差分出一个子数组
通过字典存储每次前缀和,那么当前前缀和 - 整数K,就是要求历史前缀和的值。

使用对象代替map数据类型,注意细节

  1. 对象属性名是数字时怎样读取
    取值的时候就不能用英文句号(.),只能用[]的方式
    person[5]

  2. js中将一个值转换为字符串的3种方法
    “” + value
    value.toString()
    String(value)

  3. js中检测对象中是否存在某个属性
    直接数字 in 对象也可以,if(cal-k in dic)

最后代码

var subarraySum = function(nums, k) {
    const dic = {0:1}
    let cal = 0, count=0;
    for (let i = 0; i < nums.length; i++) {
        // 当前前缀和
        cal += nums[i];
        if(dic[cal-k]){
            count += dic[cal-k]
        }
        // 成为历史前缀和
        if(dic[cal]){
            dic[cal]++;
        }else{
            dic[cal] = 1
        }
    }
    return count
};

前缀和主要适⽤的场景是原始数组不会被修 改的情况下,频繁查询某个区间的累加和。


差分数组的主要适⽤场景是频繁对原始数组的 某个区间的元素进⾏增减。
这个概念需要举例:diff[i] 就是 nums[i] 和 nums[i-1] 之差,通过这个 diff 差分数组是可以反推出原始数组 nums 的。
在这里插入图片描述

在这里插入图片描述

1109.航班预订统计
初始化二维数组

let arr=new Array(5).fill(0).map(item=>new Array(5).fill(0))
arr[1][1]=1
console.log(arr)

注意细节:

  1. end的位置是否为最后一个,是则没有后面元素减操作
  2. 根据差分数组还原数组,是 t(i) = t(i-1)+ diff(i)
  3. 题目的索引是从1开始,所以start和end的位置-1

st = v[0]-1
en = v[1] 不减1指区间后一个

1094.拼车
车上最初有 capacity 个空座位可以用来载客。这儿有一份乘客行程计划表 trips[][],其中 trips[i] = [num_passengers, start_location, end_location] 包含了第 i 组乘客的行程信息:
必须接送的乘客数量;
乘客的上车地点;
以及乘客的下车地点。

思想:要能联系到差分数组,每个地点都是数组中的一个元素,每个地点也代表某一个静止的时刻。所以检查每个元素值是否超标,检查每一次上下车是否顺利。
细节:

  1. 车站个数0 <= trips[i][1] < trips[i][2] <= 1000
  2. 第trip[2]站乘客已经下车,即乘客在车上的区间是[ trip[1],trip[2] )

en = v[2] 不用加1 因为本来区间最右边是开区间

var carPooling = function(trips, capacity) {
    let diff = new Array(1001).fill(0)
    let maxend=0, st,en
    for(v of trips){
        // console.log(v)
        st = v[1]
        en = v[2]
        maxend = Math.max(en,maxend)
        diff[st] += v[0]
        if (en <= 1000){
            diff[en] -= v[0]
        }
    }
    console.log(maxend)
    let res = new Array(maxend+1).fill(0)
    res[0] = diff[0]
    for (let i=1; i<res.length; i++){
        if(res[i-1]>capacity) return false
        res[i] = res[i-1] + diff[i]
    }
    return true
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值