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() ;
    }
};
相关推荐
XYY36913 分钟前
搜索与图论 树的深度优先遍历 树的重心
算法
破东风29 分钟前
leetcode每日一题:替换子串得到平衡字符串
算法·leetcode·滑动窗口
Hole_up38 分钟前
蓝桥杯真题-分糖果-题解
python·算法·职场和发展·蓝桥杯
十五年专注C++开发1 小时前
QT 中的元对象系统(五):QMetaObject::invokeMethod的使用和实现原理
开发语言·数据结构·c++·qt·设计模式
泛舟起晶浪1 小时前
特殊的质数肋骨--dfs+isp
算法·深度优先
GGBondlctrl1 小时前
【leetcode】记录与查找:哈希表的题型分析
算法·力扣·两数之和·字母异位词分组·存在重复字符2
熬夜学编程的小王1 小时前
【C++初阶篇】C++中c_str函数的全面解析
c语言·c++·c_str
视觉AI1 小时前
研究下适合部署在jeston上的深度学习类单目标跟踪算法
深度学习·算法·目标跟踪
一线灵1 小时前
跨平台游戏引擎 axmol-2.5.0 发布
c++·游戏引擎·wasm·axmol
渴望脱下狼皮的羊1 小时前
C++基础讲解
开发语言·c++·后端