Leetcode3250:单调数组对的数目 I

题目描述:

给你一个长度为 n 整数数组 nums

如果两个 非负 整数数组 (arr1, arr2) 满足以下条件,我们称它们是 单调 数组对:

  • 两个数组的长度都是 n
  • arr1 是单调非递减 的,换句话说 arr1[0] <= arr1[1] <= ... <= arr1[n - 1]
  • arr2 是单调 非递增 的,换句话说 arr2[0] >= arr2[1] >= ... >= arr2[n - 1]
  • 对于所有的 0 <= i <= n - 1 都有 arr1[i] + arr2[i] == nums[i]

请你返回所有 单调 数组对的数目。

由于答案可能很大,请你将它对 109 + 7 取余 后返回。

代码思路:

代码使用了动态规划和前缀和的技巧。以下是代码的详细思路:

  1. 定义常量 MODconst int MOD = 1e9 + 7; 定义了一个常量 MOD,用于对结果进行模运算,以避免整数溢出并保持结果在一个可控的范围内。

  2. 类和方法 :定义了一个 Solution 类,其中包含一个 countOfPairs 方法,该方法接收一个整数向量 nums 并返回一个整数,表示满足条件的数对数量。

  3. 初始化累加数组 acc

    • vector<int> acc(nums[0] + 1, 0); 初始化一个大小为 nums[0] + 1 的数组 acc,所有元素初始化为 0。
    • iota(acc.begin(), acc.end(), 1); 使用 iota 函数将 acc 数组填充为从 1 到 nums[0] 的连续整数。这里的 iota 函数来自 <numeric> 头文件,用于生成一个递增序列。
    • acc 数组用于存储到当前位置为止,所有可能的 nums[i] ^ nums[j](其中 j < i)小于 nums[i] 的数对数量。
  4. 遍历数组 nums

    • 使用一个迭代器 pnums 的第二个元素开始遍历到最后一个元素。
    • 对于每个 nums[p],创建一个新的临时数组 temp,用于存储计算过程中的中间结果。
  5. 计算部分和

    • 使用 partial_sum 函数计算 acc 数组中部分元素的和,但只考虑那些可能对当前 nums[p] 产生贡献的元素。
    • partial_sum 的起始范围是 acc.begin()acc.begin() + min(*p, p[-1]) + 1,这确保了只考虑那些异或结果可能小于 nums[p] 的元素。
    • temp.begin() + max(0, *p - p[-1]) 确定了 temp 数组中开始累加的位置,因为只有当 nums[i] ^ nums[j] 的结果落在 [0, nums[p] - 1] 范围内时,数对 (i, p) 才是有效的。
    • 使用自定义的 lambda 函数 [](int sum, int a) { return (sum + a) % MOD; } 来计算累加和,并对结果取 MOD
  6. 更新 acc 数组

    • temp 数组赋值给 acc,为下一次迭代做准备。
  7. 返回结果

    • 最后,acc.back() 存储了整个 nums 数组遍历完成后,所有可能的 nums[i] ^ nums[j] 小于 nums[j] 的数对数量。

代码实现:

cpp 复制代码
const int MOD = 1e9 + 7;
class Solution {
public:
    int countOfPairs(vector<int>& nums) {
        vector<int> acc(nums[0] + 1, 0);
        iota(acc.begin(), acc.end(), 1);

        for (auto&& p = nums.begin() + 1; p != nums.end(); p++) {
            vector<int> temp(*p + 1, 0);
            partial_sum(acc.begin(), acc.begin() + min(*p,p[-1]) + 1, temp.begin() + max(0,*p-p[-1]),
                        [](int sum, int a) { return (sum + a) % MOD; });
            acc = temp;
        }
        return acc.back() ;
    }
};
相关推荐
Run_Teenage3 小时前
手撕——贪吃蛇小游戏(下)
c语言·数据结构·链表
PXM的算法星球4 小时前
【leetcode】3524 求出数组的X值1
算法·leetcode·职场和发展
椰羊~王小美6 小时前
LeetCode -- Flora -- edit 2025-04-27
算法·leetcode·职场和发展
charade3127 小时前
【C语言】内存分配的理解
c语言·开发语言·c++
缘友一世7 小时前
从线性回归到逻辑回归
算法·逻辑回归·线性回归
前端_学习之路8 小时前
javaScript--数据结构和算法
javascript·数据结构·算法
weixin_428498498 小时前
使用HYPRE库并行装配IJ稀疏矩阵指南: 矩阵预分配和重复利用
算法·矩阵
雾削木10 小时前
mAh 与 Wh:电量单位的深度解析
开发语言·c++·单片机·嵌入式硬件·算法·电脑
__lost10 小时前
小球在摆线上下落的物理过程MATLAB代码
开发语言·算法·matlab
8RTHT11 小时前
数据结构(七)---链式栈
数据结构