Medium
题目描述
给你一个长度为 n 的数组 original 和一个长度为 n x 2 的二维数组 bounds,其中 bounds[i] = [ui, vi]。
你需要找到长度为 n 的可能数组 copy 的数量,使得:
(copy[i] - copy[i - 1]) == (original[i] - original[i - 1])对于1 <= i <= n - 1ui <= copy[i] <= vi对于0 <= i <= n - 1
返回这样的数组数量。
示例 1:
输入:original = [1,2,3,4], bounds = [[1,2],[2,3],[3,4],[4,5]]
输出:2
解释:
可能的数组是:
[1, 2, 3, 4]
[2, 3, 4, 5]
示例 2:
输入:original = [1,2,3,4], bounds = [[1,10],[2,9],[3,8],[4,7]]
输出:4
解释:
可能的数组是:
[1, 2, 3, 4]
[2, 3, 4, 5]
[3, 4, 5, 6]
[4, 5, 6, 7]
示例 3:
输入:original = [1,2,1,2], bounds = [[1,1],[2,3],[3,3],[2,3]]
输出:0
解释:
没有可能的数组。
约束条件:
2 <= n == original.length <= 10^51 <= original[i] <= 10^9bounds.length == nbounds[i].length == 21 <= bounds[i][0] <= bounds[i][1] <= 10^9
解题思路
这道题的核心思想是理解题目约束条件的含义。由于 copy 数组与 original 数组相邻元素的差值必须相同,这意味着一旦确定了 copy[0] 的值,整个 copy 数组就完全确定了。
具体来说,如果 copy[0] = x,那么:
copy[1] = x + (original[1] - original[0])copy[2] = x + (original[2] - original[0])- …
copy[i] = x + (original[i] - original[0])
因此,我们需要找到有多少个 x 值使得对于所有的 i,都有 bounds[i][0] <= copy[i] <= bounds[i][1]。
算法步骤:
- 首先确定
copy[0]的初始范围:[bounds[0][0], bounds[0][1]] - 对于每个后续位置
i,计算如果copy[0] = x,那么copy[i]的值 - 根据
bounds[i]的约束,反推出copy[0]的有效范围 - 取所有约束的交集,得到最终的有效范围
- 返回有效范围的大小
关键是要处理整数溢出和边界情况,确保计算过程中的数值在合理范围内。
代码实现
class Solution {
public:
int countArrays(vector<int>& original, vector<vector<int>>& bounds) {
long long minVal = bounds[0][0];
long long maxVal = bounds[0][1];
int n = original.size();
for (int i = 1; i < n; i++) {
long long diff = (long long)original[i] - original[0];
// copy[i] = copy[0] + diff
// bounds[i][0] <= copy[0] + diff <= bounds[i][1]
// bounds[i][0] - diff <= copy[0] <= bounds[i][1] - diff
long long newMin = (long long)bounds[i][0] - diff;
long long newMax = (long long)bounds[i][1] - diff;
minVal = max(minVal, newMin);
maxVal = min(maxVal, newMax);
if (minVal > maxVal) {
return 0;
}
}
return (int)(maxVal - minVal + 1);
}
};
class Solution:
def countArrays(self, original: List[int], bounds: List[List[int]]) -> int:
min_val = bounds[0][0]
max_val = bounds[0][1]
n = len(original)
for i in range(1, n):
diff = original[i] - original[0]
# copy[i] = copy[0] + diff
# bounds[i][0] <= copy[0] + diff <= bounds[i][1]
# bounds[i][0] - diff <= copy[0] <= bounds[i][1] - diff
new_min = bounds[i][0] - diff
new_max = bounds[i][1] - diff
min_val = max(min_val, new_min)
max_val = min(max_val, new_max)
if min_val > max_val:
return 0
return max_val - min_val + 1
public class Solution {
public int CountArrays(int[] original, int[][] bounds) {
long minVal = bounds[0][0];
long maxVal = bounds[0][1];
int n = original.Length;
for (int i = 1; i < n; i++) {
long diff = (long)original[i] - original[0];
// copy[i] = copy[0] + diff
// bounds[i][0] <= copy[0] + diff <= bounds[i][1]
// bounds[i][0] - diff <= copy[0] <= bounds[i][1] - diff
long newMin = bounds[i][0] - diff;
long newMax = bounds[i][1] - diff;
minVal = Math.Max(minVal, newMin);
maxVal = Math.Min(maxVal, newMax);
if (minVal > maxVal) {
return 0;
}
}
return (int)(maxVal - minVal + 1);
}
}
var countArrays = function(original, bounds) {
let minVal = bounds[0][0];
let maxVal = bounds[0][1];
const n = original.length;
for (let i = 1; i < n; i++) {
const diff = original[i] - original[0];
// copy[i] = copy[0] + diff
// bounds[i][0] <= copy[0] + diff <= bounds[i][1]
// bounds[i][0] - diff <= copy[0] <= bounds[i][1] - diff
const newMin = bounds[i][0] - diff;
const newMax = bounds[i][1] - diff;
minVal = Math.max(minVal, newMin);
maxVal = Math.min(maxVal, newMax);
if (minVal > maxVal) {
return 0;
}
}
return maxVal - minVal + 1;
};
复杂度分析
| 复杂度类型 | 值 | 说明 |
|---|---|---|
| 时间复杂度 | O(n) | 需要遍历数组一次,每次操作为常数时间 |
| 空间复杂度 | O(1) | 只使用常数额外空间存储范围边界 |
相关题目
- . Count of Range Sum (Hard)