首页 > 其他分享 >差分数组

差分数组

时间:2024-01-28 20:34:32浏览次数:23  
标签:int res 差分 df length 数组 diff

构造差分数组

 int* constructDifferenceArray(int* nums, int length) {
int* diff = (int*)malloc(length * sizeof(int));
diff[0] = nums[0];
for (int i = 1; i < length; i++) {
diff[i] = nums[i] - nums[i - 1];
}
return diff;
}

通过这个 diff 差分数组是可以反推出原始数组 nums 的,代码逻辑如下:

// 构造结果数组
int* constructResultArray(int* diff, int length) {
int* res = (int*)malloc(length * sizeof(int));
res[0] = diff[0];
for (int i = 1; i < length; i++) {
res[i] = res[i - 1] + diff[i];
}
return res;
}

这样构造差分数组 diff,就可以快速进⾏区间增减的操作,如果你想对区间 nums[i..j] 的元素全部加
3,那么只需要让 diff[i] += 3,然后再让 diff[j+1] -= 3 即可

原理很简单,回想 diff 数组反推 nums 数组的过程,diff[i] += 3 意味着给 nums[i..] 所有的元素都
加了 3,然后 diff[j+1] -= 3 ⼜意味着对于 nums[j+1..] 所有元素再减 3,那综合起来,是不是就是对
nums[i..j] 中的所有元素都加 3 了?

只要花费 O(1) 的时间修改 diff 数组,就相当于给 nums 的整个区间做了修改。多次修改 diff,然后通过
diff 数组反推,即可得到 nums 修改后的结果。

区间加法

#include <stdio.h>
#include <stdlib.h>

// 结构体表示差分数组
typedef struct {
int* array;
int length;
} Difference;

// 初始化差分数组
Difference* initDifferenceArray(int length) {
Difference* df = (Difference*)malloc(sizeof(Difference));
df->array = (int*)malloc(length * sizeof(int));
df->length = length;
for (int i = 0; i < length; i++) {
df->array[i] = 0;
}
return df;
}

// 实现 increment 函数
void increment(Difference* df, int start, int end, int val) {
df->array[start] += val;
if (end + 1 < df->length) {
df->array[end + 1] -= val;
}
}

// 计算结果数组
int* result(Difference* df) {
int* res = (int*)malloc(df->length * sizeof(int));
int sum = 0;
for (int i = 0; i < df->length; i++) {
sum += df->array[i];
res[i] = sum;
}
return res;
}

int* getModifiedArray(int length, int updates[][3], int updatesLength) {
// 初始化差分数组
Difference* df = initDifferenceArray(length);

// 构造差分数组
for (int i = 0; i < updatesLength; i++) {
int start = updates[i][0];
int end = updates[i][1];
int val = updates[i][2];
increment(df, start, end, val);
}

// 计算结果数组
int* res = result(df);

// 释放内存
free(df->array);
free(df);
return res;
}

int main() {
int updates[3][3] = { {1, 3, 2}, {2, 4, 3}, {0, 2, -2} };
int length = 5;
int updatesLength = sizeof(updates) / sizeof(updates[0]);

// 获取修改后的数组
int* modifiedArray = getModifiedArray(length, updates, updatesLength);

// 输出修改后的数组
printf("修改后的数组:");
for (int i = 0; i < length; i++) {
printf("%d ", modifiedArray[i]);
}
printf("\n");

// 释放内存
free(modifiedArray);
return 0;
}

航班预订统计

一样

拼车

你是⼀个开公交⻋的司机,公交⻋的最⼤载客量为 capacity,沿途要经过若⼲⻋站,给你⼀份乘客⾏程表
int[][] trips,其中 trips[i] = [num, start, end] 代表着有 num 个旅客要从站点 start 上⻋,
到站点 end 下⻋,请你计算是否能够⼀次把所有旅客运送完毕(不能超过最⼤载客量 capacity)。

#include <stdio.h>
#include <stdlib.h>

// 结构体表示差分数组
typedef struct {
int* array;
int length;
} Difference;

// 初始化差分数组
Difference* initDifferenceArray(int length) {
Difference* df = (Difference*)malloc(sizeof(Difference));
df->array = (int*)malloc(length * sizeof(int));
df->length = length;
for (int i = 0; i < length; i++) {
df->array[i] = 0;
}
return df;
}

// 实现 increment 函数
void increment(Difference* df, int start, int end, int val) {
df->array[start] += val;
if (end + 1 < df->length) {
df->array[end + 1] -= val;
}
}

// 计算结果数组
int* result(Difference* df) {
int* res = (int*)malloc(df->length * sizeof(int));
int sum = 0;
for (int i = 0; i < df->length; i++) {
sum += df->array[i];
res[i] = sum;
}
return res;
}

// 判断是否能完成乘客运送
int carPooling(int trips[][3], int tripsLength, int capacity) {
// 初始化差分数组
Difference* df = initDifferenceArray(1001);

// 构造差分数组
for (int i = 0; i < tripsLength; i++) {
int val = trips[i][0];
int start = trips[i][1];
int end = trips[i][2] - 1;
increment(df, start, end, val);
}

// 计算结果数组
int* res = result(df);

// 客车自始至终都不应该超载
for (int i = 0; i < 1001; i++) {
if (capacity < res[i]) {
free(df->array);
free(df);
free(res);
return 0;
}
}
  
free(df->array);
free(df);
free(res);
  
return 1;
}

int main() {
int trips[3][3] = {{2, 1, 5}, {3, 3, 7}, {3, 8, 10}};
int capacity = 4;
int tripsLength = sizeof(trips) / sizeof(trips[0]);

// 是否能完成乘客运送
int result = carPooling(trips, tripsLength, capacity);

// 输出结果
if (result) {
printf("能够一次把所有旅客运送完毕\n");
} else {
printf("不能一次把所有旅客运送完毕\n");
}

return 0;
}

标签:int,res,差分,df,length,数组,diff
From: https://www.cnblogs.com/lulixiu1999/p/17993262

相关文章

  • 数组前缀和
    一维数组中的前缀和https://leetcode.com/problems/range-sum-query-immutable/description/区域和检索#include<stdio.h>#include<stdlib.h>//定义NumArray结构体typedefstruct{int*preSum;//前缀和数组}NumArray;//创建NumArray对象,并计算前缀和数组......
  • Java中的数组
    数组1、数组概述数组是相同类型数据的有序集合数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们2、数组声明创建首先必须声明数组变量,才能在程序中使用数组。下面是声明数......
  • 【学习笔记】差分约束
    前言2024.1.27\(huge\)在讲不要忽略算法的细节时,以最短路和差分约束为例子。发现自己差分约束忘得差不多了,于是就有了这篇博客。负环在一张图中,若存在一条边权之和为负数的回路,则称这个回路为负环。在一张图中,若存在一条边权之和为正数的回路,则称这个回路为正环。如果一张......
  • 前缀和与差分典题
    includeusingnamespacestd;constintN=1010;inta[N][N],b[N][N];voidinsert(intx1,inty1,intx2,inty2,intc){b[x1][y1]+=c;b[x2+1][y1]-=c;b[x1][y2+1]-=c;b[x2+1][y2+1]+=c;}intmain(){intn,m,q,w;scanf("%d%d%d",&n,&m,&......
  • 数组:讲解一维数组和多维数组的声明、初始化和访问。
    一维数组是最简单的数组形式,它可以存储一系列相同类型的元素。多维数组则是由多个一维数组组成的数据结构,可以用于存储多维数据。下面我将分别讲解一维数组和多维数组的声明、初始化和访问。一维数组一维数组的声明和初始化可以分为两步进行。声明一维数组在C语言中,可以使用以下语......
  • 80. 删除有序数组中的重复项 II(中)
    目录题目题解:双指针题目给你一个有序数组nums,请你原地删除重复出现的元素,使得出现次数超过两次的元素只出现两次,返回删除后数组的新长度。不要使用额外的数组空间,你必须在原地修改输入数组并在使用O(1)额外空间的条件下完成。说明:为什么返回数值是整数,但输......
  • 动态区间求和——树状数组的基本应用
    目录前言问题引入思路一览具体分析前言准确来说,不应该叫做动态区间求和问题,只能说树状数组经常用于求和操作而已,但是正常的动态条件查询树状数组也是可以做的,具体的下面再说吧问题引入给出一个数组a[],要求做两种操作,一种是修改数组中的一个数,一种是实现查询区间[lt,rt](lt<=......
  • C#数组对象池ArrayPool<T>底层
    深度解析C#数组对象池ArrayPool<T>底层原理 提到池化技术,很多同学可能都不会感到陌生,因为无论是在我们的项目中,还是在学习的过程的过程,都会接触到池化技术。池化技术旨在提高资源的重复使用和系统性能,在.NET中包含以下几种常用的池化技术。(1)、连接池(Connecti......
  • 【板子】树状数组(BIT)
    //lg1908求逆序对//Copyrightyeyou26#include<bits/stdc++.h>usingnamespacestd;#definelllonglongconstintN=(int)1e6+6;llsum;intn;structData{intorigin;intls;intid;}data[N];boolcmporigin(Datax,Datay){r......
  • 树状数组(区间修改&&区间查询)
    #include<bits/stdc++.h> #defineintlonglongusingnamespacestd;intn,m,x,x1,y,z;inta[100010],d[100010],c[100010];intlowbit(intnum){returnnum&-num;}voidadd(intx,inty){ inta=x; while(x<=n)d[x]+=y,c[x]+=(a-1)*y,x+=lowbit(x); ......