滑动子数组的美丽值
难度:
标签:
题目描述
Given an integer array nums
containing n
integers, find the beauty of each subarray of size k
.
The beauty of a subarray is the xth
smallest integer in the subarray if it is negative, or 0
if there are fewer than x
negative integers.
Return an integer array containing n - k + 1
integers, which denote the beauty of the subarrays in order from the first index in the array.
-
A subarray is a contiguous non-empty sequence of elements within an array.
Example 1:
Input: nums = [1,-1,-3,-2,3], k = 3, x = 2 Output: [-1,-2,-2] Explanation: There are 3 subarrays with size k = 3. The first subarray is[1, -1, -3]
and the 2nd smallest negative integer is -1. The second subarray is[-1, -3, -2]
and the 2nd smallest negative integer is -2. The third subarray is[-3, -2, 3]
and the 2nd smallest negative integer is -2.
Example 2:
Input: nums = [-1,-2,-3,-4,-5], k = 2, x = 2 Output: [-1,-2,-3,-4] Explanation: There are 4 subarrays with size k = 2. For[-1, -2]
, the 2nd smallest negative integer is -1. For[-2, -3]
, the 2nd smallest negative integer is -2. For[-3, -4]
, the 2nd smallest negative integer is -3. For[-4, -5]
, the 2nd smallest negative integer is -4.
Example 3:
Input: nums = [-3,1,2,-3,0,-3], k = 2, x = 1 Output: [-3,0,-3,-3,-3] Explanation: There are 5 subarrays with size k = 2. For[-3, 1]
, the 1st smallest negative integer is -3. For[1, 2]
, there is no negative integer so the beauty is 0. For[2, -3]
, the 1st smallest negative integer is -3. For[-3, 0]
, the 1st smallest negative integer is -3. For[0, -3]
, the 1st smallest negative integer is -3.
Constraints:
n == nums.length
1 <= n <= 105
1 <= k <= n
1 <= x <= k
-50 <= nums[i] <= 50
代码结果
运行时间: 375 ms, 内存: 25.9 MB
import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* 给定一个整数数组 nums 和两个整数 k 和 x, 使用 Java Stream API 求出每个长度为 k 的子数组的美丽值。
* 美丽值定义为:如果子数组中第 x 小的整数是负数,则美丽值为该数;否则为 0。
*/
public class Solution {
public int[] getBeautyValues(int[] nums, int k, int x) {
return IntStream.rangeClosed(0, nums.length - k)
.map(i -> Arrays.stream(nums, i, i + k)
.sorted()
.toArray()[x - 1])
.map(value -> value < 0 ? value : 0)
.toArray();
}
public static void main(String[] args) {
Solution sol = new Solution();
int[] nums = {1, -1, -3, -2, 3};
int k = 3;
int x = 2;
System.out.println(Arrays.toString(sol.getBeautyValues(nums, k, x)));
}
}
解释
方法:
此题解使用滑动窗口和直接数组索引的方法来维护和更新子数组内元素的计数,从而实时获取子数组内第x小的值。初始化时,首先统计前k个元素的计数,然后寻找当前第x小的值。在随后的滑动窗口操作中,对每次滑动窗口的移动,都会调整计数数组,并重新确定第x小的值。如果新计算出的第x小的值是负数,则记录此值;如果不是,则记录0。此方法避免了对每个窗口内的所有元素进行排序,大大提高了效率。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
在题解中提到使用计数数组d来维护子数组元素的计数,这种方法是否考虑了nums数组中可能存在的超出[-50, 50]范围的值?
▷🦆
题解中提到,计数数组的大小为101,这是基于什么考虑?如果输入数组nums的范围更广,比如[-1000, 1000],这种方法还适用吗?
▷🦆
在寻找第x小的数时,题解使用了线性遍历计数数组的方式,这种方式的效率如何?存在更优的查找方法吗?
▷🦆
题解中的滑动窗口更新过程中,对于每次窗口移动后重新计算第x小的值的过程中,是否有可能出现cnt计数错误的情况?如何确保其准确性?
▷