来源:【算法小课堂】差分数组
1109. 航班预订统计
1109. 航班预订统计
根据题意,需要返回一个数组,其中每个元素是当前航班的预定座位的个数。
在预定记录 bookings
中,每一个预订记录实际上代表了一个区间的增量,因此结果就可以从这些增量叠加得到答案。因此,我们可以使用差分解决本题。
差分数组的性质是,当我们希望对原数组的某一个区间 [l,r]
施加一个增量 inc
时,差分数组 d
对应的改变是:d[l]
增加 inc
,d[r+1]
减少 inc
。其中,d[r+1]
减少 inc
的原因是,d
中的后续区间元素需要消除 inc
的影响,否则在从左到右累加 d 中的元素时 r+1
以及后续的元素都会再加上 inc
,导致出错。
注意本题中航班的编号从 1 到 n 的,因此我们需要相应的调整数组下标对应关系,对于预定记录 booking=[l,r,inc]
,我们需要让 d[l−1] += inc
,d[r] -= inc
。特别地,当 r = n
时,我们无需修改 d[r]
,因为这个位置溢出了下标范围。
class Solution {
public:
vector<int> corpFlightBookings(vector<vector<int>>& bookings, int n) {
vector<int> d (n);
for (auto& b : bookings) {
d[b[0]-1] += b[2];
if (b[1] < n) d[b[1]] -= b[2];
}
for (int i=1; i < n; i++)
d[i] += d[i-1];
return d;
}
};
/**
* @param {number[][]} bookings
* @param {number} n
* @return {number[]}
*/
var corpFlightBookings = function(bookings, n) {
const diff = Array(n).fill(0);
for ([first, last, num] of bookings) {
diff[first-1] += num;
if (last < n) diff[last] -= num;
}
for (let i=1; i < n; i++)
diff[i] += diff[i-1];
return diff;
};
2381. 字母移位 II
2381. 字母移位 II
根据题意,将小写英文字母组成的字符串 s
里的字符都进行移位运算,最终返回移位后最终字符串。在 shifts
中,每一个元素实际上代表了一个区间内字符的位移情况,因此结果就可以从这些位移叠加得到答案。因此,我们可以使用差分解决本题。
用差分数组 diff
表示一段区间上的移位,即在
s
t
a
r
t
i
start_i
starti 变化量增加了
x
x
x,在
e
n
d
i
+
1
end_i+1
endi+1 变化量减少了
x
x
x。
其中
x
x
x 是根据
d
i
r
e
c
t
i
o
n
i
direction_i
directioni 求得:
当
d
i
r
e
c
t
i
o
n
i
=
1
direction_i=1
directioni=1 时,diff[start_i] += 1
,diff[end_i+1] -= 1
;
当
d
i
r
e
c
t
i
o
n
i
=
0
direction_i=0
directioni=0 时,diff[start_i] -= 1
,diff[end_i+1] += 1
。
最后,从小到大遍历 diff
,累加变化量为
d
d
d,这样对于第
i
i
i 个字符,其移位值就是
d
d
d。
/**
* @param {string} s
* @param {number[][]} shifts
* @return {string}
*/
var shiftingLetters = function(s, shifts) {
const n = s.length;
const diff = Array(n+1).fill(0);
for (x of shifts) {
diff[x[0]] = x[2] == 1 ? diff[x[0]] + 1 : diff[x[0]] - 1;
diff[x[1]+1] = x[2] == 1 ? diff[x[1]+1] - 1 : diff[x[1]+1] + 1;
}
let d = 0;
let ans = '';
for (let i=0; i < n; i++) {
d += diff[i];
let newCharCode = (s.charCodeAt(i) - 'a'.charCodeAt(0) + d) % 26; // 计算新的字符
if (newCharCode < 0) newCharCode += 26; // 防止负数出现
ans += String.fromCharCode(newCharCode + 'a'.charCodeAt(0)); // 拼接新字符
}
return ans;
};