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() ;
    }
};
相关推荐
颜x小24 分钟前
[C#] C++与c#语法对比
开发语言·c++·c#
ldmd28425 分钟前
地图生成算法(噪声篇-Perlin,Simplex,Value noise)
算法·go·地图生成
国科安芯43 分钟前
FreeRTOS RISC-V 浮点上下文切换移植:在 IAR 工程中完整保存 FPU 寄存器
java·开发语言·单片机·嵌入式硬件·算法·系统架构·risc-v
小陈phd1 小时前
集成检索介绍
算法
小poop1 小时前
轮转数组:从暴力到最优,一题掌握算法复杂度分析
数据结构·算法·leetcode
樱桃读报僵尸2 小时前
说说 LLMRouter,Agent 执行过程中怎么动态的选择 LLM
算法
汉克老师2 小时前
GESP2026年3月认证C++八级( 第三部分编程题(2、子图最短路)精讲
c++·最短路·floyd·gesp8级
gis开发之家2 小时前
《Vue3 从入门到大神40篇》Vue3 源码详解(十):diff 算法全解析 —— 为什么 Vue3 比 Vue2 更快?
javascript·算法·typescript·前端框架·vue3·vue3源码
进击的丸子3 小时前
虹软人脸服务器SDK-C++语言Demo实操指南
后端·算法
abcd_zjq3 小时前
海康线扫相机使用
c++·海康