LeetCode每日一题(2444. Count Subarrays With Fixed Bounds)

给定整数数组 nums 和两个整数 minK 和 maxK,求满足最小值为 minK、最大值为 maxK 的固定边界子数组的数量。文章通过举例解释了如何计算这种子数组的数量,并提出了关键的 'core array' 概念,通过遍历数组找出符合要求的模式并计算组合数量来解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

You are given an integer array nums and two integers minK and maxK.

A fixed-bound subarray of nums is a subarray that satisfies the following conditions:

The minimum value in the subarray is equal to minK.
The maximum value in the subarray is equal to maxK.
Return the number of fixed-bound subarrays.

A subarray is a contiguous part of an array.

Example 1:

Input: nums = [1,3,5,2,7,5], minK = 1, maxK = 5
Output: 2

Explanation: The fixed-bound subarrays are [1,3,5] and [1,3,5,2].

Example 2:

Input: nums = [1,1,1,1], minK = 1, maxK = 1
Output: 10

Explanation: Every subarray of nums is a fixed-bound subarray. There are 10 possible subarrays.

Constraints:

  • 2 <= nums.length <= 105
  • 1 <= nums[i], minK, maxK <= 106

我们给[min_k, any_nums..., max_k][max_k, any_nums..., min_k], 其中 min_k < any_nums < max_k, 这种数组起个名字叫 core array, , 就像雨水的凝结核一样, 任何数字 n, min_k <= n <= max_k, 只要附着在 core array 两侧就可以形成符合标准的 array。表达出来就是[left_nums...,min_k, any_nums, max_k, right_nums...], 只要 min_k<=left_nums<=max_k 且 min_k<=right_nums<=max_k, 那实际组成的符合标准的 subarray 的数量就应该是(count(left_nums) + 1)*(count(right_nums) + 1), 表达的意义就是 core array 左侧的任意一个数字(包括 min_k), 到 core array 右侧的任意数字(包括 max_k)所形成的 subarray 的组合数量。这里要注意 any_nums 一定不能等于 min_k 或者 max_k 的, 否则 core array 就可以收缩变成一个更小的 core array。[left_nums...,max_k, any_nums, min_k, right_nums...]与此相同只不过 min_k 与 max_k 互换一下位置。

所以我们只需要在给的 nums 中找出上面说的两种 pattern, 然后计算出所能组合的 subarray 的数量, 再将这些数量进行加和即可。



impl Solution {
    fn calc(nums: &[i32], min_k: i32, max_k: i32) -> i64 {
        if min_k == max_k {
            return (nums.len() * (nums.len() + 1) / 2) as i64;
        }
        let mut target = 0;
        let mut start_index = 0;
        for i in 0..nums.len() {
            if nums[i] == min_k {
                target = max_k;
                start_index = i;
                break;
            }
            if nums[i] == max_k {
                target = min_k;
                start_index = i;
                break;
            }
        }
        if target == 0 {
            return 0;
        }
        let mut end_index = start_index;
        for i in (start_index + 1)..nums.len() {
            if nums[i] == target {
                end_index = i;
                break;
            }
        }
        if end_index == start_index {
            return 0;
        }
        let mut ans = ((start_index + 1) * (nums.len() - end_index)) as i64;
        ans += Solution::calc(&nums[start_index + 1..], min_k, max_k);
        ans
    }
    pub fn count_subarrays(nums: Vec<i32>, min_k: i32, max_k: i32) -> i64 {
        let mut queue = Vec::new();
        let mut ans = 0;
        for n in nums {
            if n >= min_k && n <= max_k {
                queue.push(n);
                continue;
            }
            ans += Solution::calc(&queue, min_k, max_k);
            queue.clear();
        }
        ans += Solution::calc(&queue, min_k, max_k);
        ans
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值