1601. Maximum Number of Achievable Transfer Requests

1601. Maximum Number of Achievable Transfer Requests

Question

We have n buildings numbered from 0 to n - 1. Each building has a number of employees. It’s transfer season, and some employees want to change the building they reside in.

You are given an array requests where requests[i] = [fromi, toi] represents an employee’s request to transfer from building fromi to building toi.

All buildings are full, so a list of requests is achievable only if for each building, the net change in employee transfers is zero. This means the number of employees leaving is equal to the number of employees moving in. For example if n = 3 and two employees are leaving building 0, one is leaving building 1, and one is leaving building 2, there should be two employees moving to building 0, one employee moving to building 1, and one employee moving to building 2.

Return the maximum number of achievable requests.

Read more
1035. Uncrossed Lines

1035. Uncrossed Lines

Question

You are given two integer arrays nums1 and nums2. We write the integers of nums1 and nums2 (in the order they are given) on two separate horizontal lines.

We may draw connecting lines: a straight line connecting two numbers nums1[i] and nums2[j] such that:

  • nums1[i] == nums2[j], and
  • the line we draw does not intersect any other connecting (non-horizontal) line.

Note that a connecting line cannot intersect even at the endpoints (i.e., each number can only belong to one connecting line).

Return the maximum number of connecting lines we can draw in this way.

Read more
1964. Find the Longest Valid Obstacle Course at Each Position

1964. Find the Longest Valid Obstacle Course at Each Position

Question

You want to build some obstacle courses. You are given a 0-indexed integer array obstacles of length n, where obstacles[i] describes the height of the ith obstacle.

For every index i between 0 and n - 1 (inclusive), find the length of the longest obstacle course in obstacles such that:

  • You choose any number of obstacles between 0 and i inclusive.
  • You must include the ith obstacle in the course.
  • You must put the chosen obstacles in the same order as they appear in obstacles.
  • Every obstacle (except the first) is taller than or the same height as the obstacle immediately before it.

Return an array ans of length nwhere ans[i] is the length of the longest obstacle course for index i as described above.

Read more
1579. Remove Max Number of Edges to Keep Graph Fully Traversable

1579. Remove Max Number of Edges to Keep Graph Fully Traversable

Question

Alice and Bob have an undirected graph of n nodes and three types of edges:

  • Type 1: Can be traversed by Alice only.
  • Type 2: Can be traversed by Bob only.
  • Type 3: Can be traversed by both Alice and Bob.

Given an array edges where edges[i] = [typei, ui, vi] represents a bidirectional edge of type typei between nodes ui and vi, find the maximum number of edges you can remove so that after removing the edges, the graph can still be fully traversed by both Alice and Bob. The graph is fully traversed by Alice and Bob if starting from any node, they can reach all other nodes.

Return the maximum number of edges you can remove, or return -1 if Alice and Bob cannot fully traverse the graph.

Solution

对于A,B皆互通的边的权重比只对A或B连通的边的权重高。(多提供另一种联通)

因此先选择双连通的边,并加入两个并查集,由于选择了边,因此res–。

然后选择单连通的边,如果并查集中的两个节点并不互通,则选择这个边,并加入对应并查集。

每次连通两个节点,则集合数量减少1。

如果最终两个并查集的数量不是1,则并非所有节点都互相连通,返回-1。

否则返回未选择的边数res。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
class Solution {
public int maxNumEdgesToRemove(int n, int[][] edges) {
UnionFind ufA = new UnionFind(n), ufB = new UnionFind(n);
int res = edges.length;

for(int[] edge : edges){
int type = edge[0], u = edge[1] - 1, v = edge[2] - 1;
if(type == 3 && !ufA.isConnected(u, v)){
ufA.union(u, v);
ufB.union(u, v);
res--;
}

}

for(int[] edge : edges){
int type = edge[0], u = edge[1] - 1, v = edge[2] - 1;

if(type == 1 && !ufA.isConnected(u, v)){
ufA.union(u, v);
res--;
}
else if(type == 2 && !ufB.isConnected(u, v)){
ufB.union(u, v);
res--;
}
}
return ufA.sets == ufB.sets && ufA.sets == 1 ? res : -1;
}
}

class UnionFind{
int[] parent;
int[] rank;
public int sets;

UnionFind(int n){
parent = new int[n];
rank = new int[n];
sets = n;
for(int i = 0; i < n; i++){
parent[i] = i;
rank[i] = 0;
}
}

public int find(int i){
if(parent[i] == i){
return i;
}
return find(parent[i]);
}

public void union(int a, int b){
int pa = find(a), pb = find(b);
if(pa != pb) sets--;
if(rank[pa] < rank[pb]){
parent[pa] = pb;
}
else if(rank[pa] > rank[pb]){
parent[pb] = pa;
}
else{
parent[pa] = pb;
rank[pb]++;
}
}

public boolean isConnected(int a, int b){
return find(a) == find(b);
}
}
1697. Checking Existence of Edge Length Limited Paths

1697. Checking Existence of Edge Length Limited Paths

Question

An undirected graph of n nodes is defined by edgeList, where edgeList[i] = [ui, vi, disi] denotes an edge between nodes ui and vi with distance disi. Note that there may be multiple edges between two nodes.

Given an array queries, where queries[j] = [pj, qj, limitj], your task is to determine for each queries[j] whether there is a path between pj and qj such that each edge on the path has a distance strictly less than limitj .

Return a boolean array answer, where answer.length == queries.length and the jth value of answer is true if there is a path for queries[j] is true, and false otherwise.

Read more
42. Trapping Rain Water

42. Trapping Rain Water

Question

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining.

Solution

双指针,设置当前左侧的最大高度left和右侧的最大高度right。

分别从两侧遍历height[]数组,当出现更高的height时更新left和right。
否则记录left和right与height[i]的差值,并记录在数组waterLeft[]和waterRight[]中。

遍历两个数组,添加两者中的最小值到volume。

*由于单个参数只记录了一侧的最大值,因此最大值另一侧的水的体积会被多计算,因此分别从两侧遍历来获得最小值。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public int trap(int[] height) {
int n = height.length, left = 0, right = 0, volume = 0;
int[] waterLeft = new int[n], waterRight = new int[n];

for(int i = 0; i < n; i++){
if(left <= height[i]) left = height[i];
else waterLeft[i] = left - height[i];
}

for(int i = n - 1; i >= 0; i--){
if(right <= height[i]) right = height[i];
else waterRight[i] = right - height[i];
}

for(int i = 0; i < n; i++){
volume += Math.min(waterLeft[i], waterRight[i]);
}

return volume;
}
}
1383. Maximum Performance of a Team

1383. Maximum Performance of a Team

Question

You are given two integers n and k and two integer arrays speed and efficiency both of length n. There are n engineers numbered from 1 to n. speed[i] and efficiency[i] represent the speed and efficiency of the i<sup>th</sup> engineer respectively.

Choose at most k different engineers out of the n engineers to form a team with the maximum performance.

The performance of a team is the sum of their engineers’ speeds multiplied by the minimum efficiency among their engineers.

Return the maximum performance of this team. Since the answer can be a huge number, return it modulo 10<sup>9</sup><span> </span>+ 7.

Solution

排序,将所有工程师根据其效率降序排列。

此时遍历时后一个工程师的效率一定小于等于前一个工程师。

因此,此时遍历到每一个工程师,其前面所有的工程师的efficiency均大于等于其本身。
维护一个所有选取工程师的总速度ttSpd,每次计算并更新max的值。
用最小堆来维护选取的工程师速度,如果优先级队列的尺寸超过k-1,则poll掉队列内最低的速度。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Solution {
public int maxPerformance(int n, int[] speed, int[] efficiency, int k) {
final int mod = (int) Math.pow(10, 9) + 7;
int[][] engineer = new int[n][2];

for(int i = 0; i < n; i++){
engineer[i][0] = speed[i];
engineer[i][1] = efficiency[i];
}

Arrays.sort(engineer, new Comparator<int[]>(){
public int compare(int[] a, int[] b){
return b[1] - a[1];
}
});

long max = 0, ttSpd = 0;

PriorityQueue<Integer> pq = new PriorityQueue<>();
for(int i = 0; i < n; i++){
int s = engineer[i][0], e = engineer[i][1];
ttSpd += s;
max = Math.max(max, ttSpd * e);
pq.add(s);
if(pq.size() == k) ttSpd -= pq.poll();
}

return (int) (max % mod);
}
}

363. Max Sum of Rectangle No Larger Than K

363. Max Sum of Rectangle No Larger Than K

Question

Given an m x n matrix matrix and an integer k, return the max sum of a rectangle in the matrix such that its sum is no larger than k.

It is guaranteed that there will be a rectangle with a sum no larger than k.

Solution

前缀和,计算矩阵中每个位置对应的方形的和。
遍历方形的两个对角线上的点。
其面积等于大块加小块的面积减去两个长方形的面积。
如果面积有小于k的,则记录其最大值并返回。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
public int maxSumSubmatrix(int[][] matrix, int k) {
int x = matrix.length, y = matrix[0].length, max = Integer.MIN_VALUE;
int[][] sum = new int[x+1][y+1];

for(int i = 1; i <= x; i++){
int total = 0;
for(int j = 1; j <= y; j++){
total += matrix[i-1][j-1];
sum[i][j] = sum[i-1][j] + total;
}
}

for(int i = 0; i <= x; i++){
for(int j = 0; j <= y; j++){
for(int m = i + 1; m <= x; m++){
for(int n = j + 1; n <= y; n++){
int area = sum[m][n] + sum[i][j] - sum[m][j] - sum[i][n];
if(area <= k) max = Math.max(max, area);
}
}
}
}
return max;
}
}
1220. Count Vowels Permutation

1220. Count Vowels Permutation

Question

Given an integer n, your task is to count how many strings of length n can be formed under the following rules:

  • Each character is a lower case vowel ('a', 'e', 'i', 'o', 'u')

  • Each vowel 'a' may only be followed by an 'e'.

  • Each vowel 'e' may only be followed by an 'a' or an 'i'.

  • Each vowel 'i' may not be followed by another 'i'.

  • Each vowel 'o' may only be followed by an 'i' or a 'u'.

  • Each vowel 'u' may only be followed by an 'a'.

Since the answer may be too large, return it modulo 10^9 + 7.

Solution

DFS搜索,记忆化剪枝。
每次根据上一个字母last来从哈希表里选择下一个可选字母进行遍历,并计算总的可组成数sum。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class Solution {
final int MOD = (int) Math.pow(10, 9) + 7;
int[][] memo;
HashMap<Character, Character[]> map;
public int countVowelPermutation(int n) {
if(n == 1) return 5;
map = new HashMap<>();
memo = new int[26][n+1];
Character[] vowels = {'a', 'e', 'i', 'o', 'u'},
a = {'e'}, e = {'a','i'}, i = {'a','e','o','u'}, o = {'i', 'u'}, u = {'a'};
map.put('a', a);
map.put('e', e);
map.put('i', i);
map.put('o', o);
map.put('u', u);

int ans = 0;

for(char vowel : vowels){
ans += count(vowel, n-1);
ans %= MOD;
}
return ans;
}

private int count(char last, int n){
if(memo[last-'a'][n] != 0) return memo[last-'a'][n];
if(n == 1){
memo[last-'a'][n] = map.get(last).length;
return memo[last-'a'][n];
}

int sum = 0;
for(char next : map.get(last)){
sum += count(next, n-1);
sum %= MOD;
}
memo[last-'a'][n] = sum;
return sum;
}
}
135. Candy

135. Candy

Question

There are n children standing in a line. Each child is assigned a rating value given in the integer array ratings.

You are giving candies to these children subjected to the following requirements:

  • Each child must have at least one candy.
  • Children with a higher rating get more candies than their neighbors.

Return the minimum number of candies you need to have to distribute the candies to the children.

Solution

双向遍历。
先从左至右遍历数组,如果上一个数值小于当前数值,则当前糖果等于上一个糖果数+1。
然后从右至左遍历数组,同理计算right的数值。
然后保存right与left[]里较大的数值,作为需要分配的糖果数加入到res。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution {
public int candy(int[] ratings) {
int[] left = new int[ratings.length];
for(int i = 0; i < ratings.length; i++){
if(i > 0 && ratings[i] > ratings[i-1]){
left[i] = left[i-1] + 1;
}
else{
left[i] = 1;
}
}

int right = 0, res = 0;
for(int i = ratings.length-1; i >= 0; i--){
if(i < ratings.length-1 && ratings[i] > ratings[i+1]){
right++;
}
else{
right = 1;
}
res += Math.max(left[i], right);
}
return res;
}
}

2321. Maximum Score Of Spliced Array

Question

You are given two 0-indexed integer arrays nums1 and nums2, both of length n.

You can choose two integers left and right where 0 <= left <= right < n and swap the subarray nums1[left...right] with the subarray nums2[left...right].

  • For example, if nums1 = [1,2,3,4,5] and nums2 = [11,12,13,14,15] and you choose left = 1 and right = 2, nums1 becomes [1,<strong><u>12,13</u></strong>,4,5] and nums2 becomes [11,<strong><u>2,3</u></strong>,14,15].

You may choose to apply the mentioned operation once or not do anything.

The score of the arrays is the maximum of sum(nums1) and sum(nums2), where sum(arr) is the sum of all the elements in the array arr.

Return the maximum possible score.

A subarray is a contiguous sequence of elements within an array. arr[left...right] denotes the subarray that contains the elements of nums between indices left and right (inclusive).

Solution

滑动窗口。一开始想用dp解决的。
后来发现可以优化到直接记录连续的最大差值即可。
以后有提到连续的一定要想到滑动窗口实现。

辅助方法getMinContigouousDiff()用来计算两个数组间连续的最小的差值和。
当sum为负数时,窗口向右侧扩展,将新的位置加入sum,并更新最小值min。
当扩展后sum大于0时,则放弃之前的所有元素,将sum归零。
最后返回最小值min。

计算两个数组的所有数字之和t1和t2。分别计算nums1[]和nums2[]的差min1和nums2[]和nums1[]的差min2。
在其中替换连续的部分则为t1-min1,t2-min2。取两者中较大的数字返回即可。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
public int maximumsSplicedArray(int[] nums1, int[] nums2) {
int n = nums1.length;
int t1 = 0, t2 = 0;
for(int i = 0; i < n ;i++){ //计算两个数组未替换前的和
t1 += nums1[i];
t2 += nums2[i];
}
int min1 = getMinContiguousDiff(nums2, nums1);
int min2 = getMinContiguousDiff(nums1, nums2);
return Math.max(t1 - min1, t2 - min2); //替换连续的部分,两者中取最大值
}

private int getMinContiguousDiff(int[] nums1, int[] nums2){ //滑动窗口,求连续元素间的最小差值
int sum = 0, min = 0;
for(int i = 0; i < nums1.length; i++){
if(sum <= 0){ //当sum为负数时,窗口向右侧扩展,将新的位置加入sum
int diff = nums2[i] - nums1[i];
sum += diff;
if(diff < 0) min = Math.min(min, sum); //更新最小值
if(sum > 0) sum = 0; //当sum为正数时,抛弃前面的元素,重新开始计算sum
}
}
return min;
}
}

2318. Number of Distinct Roll Sequences

Question

You are given an integer n. You roll a fair 6-sided dice n times. Determine the total number of distinct sequences of rolls possible such that the following conditions are satisfied:

  1. The greatest common divisor of any adjacent values in the sequence is equal to 1.
  2. There is at least a gap of 2 rolls between equal valued rolls. More formally, if the value of the i<sup>th</sup> roll is equal to the value of the j<sup>th</sup> roll, then abs(i - j) > 2.

Return the* total number** of distinct sequences possible*. Since the answer may be very large, return it modulo 10<sup>9</sup><span> </span>+ 7.

Two sequences are considered distinct if at least one element is different.

Solution

DFS+记忆化搜索剪枝。
辅助方法getValidNext计算前两个位置为last1和last2时的所有的下一个有效值,将返回值储存在next[][]数组中。

DFS搜索

DFS搜索,传入剩余骰子数量n,前两个骰子的值x和y。
从next[x][y]中得到所有有效值。并进行递归。
将返回结果加和并返回。
当n等于0时,只有一个组合,因此返回1。

记忆化搜索

在搜索时会重复计算很多相同的x,y与n的组合,因此可以采用记忆化搜索进行剪枝。
用memo[][][]数组记录x,y与n的状态。如果此前已经计算过其结果,则直接返回memo[x][y][n]。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Solution {
List<Integer>[][] next;
int[][][] memo;
public int distinctSequences(int n) {
next = new ArrayList[7][7];
for(int i = 0; i <= 6; i++){
for(int j = 0; j <= 6; j++){
next[i][j] = getValidNext(i, j);
}
}
memo = new int[7][7][10001];
return count(n, 0, 0);
}

private int count(int n, int x, int y){
if(n == 0) return 1;
if(memo[x][y][n] != 0) return memo[x][y][n];
List<Integer> validNext = next[x][y];
int sum = 0;
for(int z : validNext){
sum += count(n-1, y, z);
sum %= 1000000007;
}
memo[x][y][n] = sum;
return sum;
}

private List<Integer> getValidNext(int last1, int last2){
List<Integer> arr = new ArrayList<>();
for(int i = 1; i <= 6; i++){
if(last1 == 0 && last2 == 0) arr.add(i);
else if(i == last1 || i == last2) continue;
else if((last2 & 1) == 0 && (i & 1) == 0) continue;
else if((last2 == 3 || last2 == 6) && (i == 3 || i == 6)) continue;
else arr.add(i);
}
return arr;
}
}
630. Course Schedule III

630. Course Schedule III

Question

There are n different online courses numbered from 1 to n. You are given an array courses where courses[i] = [duration<sub>i</sub>, lastDay<sub>i</sub>] indicate that the i<sup>th</sup> course should be taken continuously for duration<sub>i</sub> days and must be finished before or on lastDay<sub>i</sub>.

You will start on the 1<sup>st</sup> day and you cannot take two or more courses simultaneously.

Return the maximum number of courses that you can take.

Solution

贪心算法,优先级队列实现。
优先选择截止日期更短的课程。
优先级队列pq记录当前已选课程,按持续时间从长到短排列。
同时维护当前的日期curDay。

当当前选择的课程截止日期晚于curDay加上当前的持续时间duration时,查看大根堆里最长的课程longestDuration。如果最长的时间大于当前时间,则将其挤出,并将当前课程加入。

如果当前课程截止日期晚于curDay,则直接将其加入队列中,并更新curDay。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
public int scheduleCourse(int[][] courses) {
Arrays.sort(courses, (a, b) -> a[1] - b[1]);
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> b[0] - a[0]);
int curDay = 0;
for(int[] course : courses){
int duration = course[0];
int lastDay = course[1];

if(curDay + duration > lastDay){ //大于截止日期
if(pq.isEmpty()) continue;
int longestDuration = pq.peek()[0];
if(longestDuration > duration){ //替换到当前队列中持续日期最长的课程
curDay -= pq.poll()[0];
curDay += duration;
pq.offer(course);
}
}
else{ //小于截止日期则加入选课
curDay += duration;
pq.offer(course);
}
}
return pq.size();
}
}
1354. Construct Target Array With Multiple Sums

1354. Construct Target Array With Multiple Sums

Question

You are given an array target of n integers. From a starting array arr consisting of n 1’s, you may perform the following procedure :

  • let x be the sum of all elements currently in your array.
  • choose index i, such that 0 <= i < n and set the value of arr at index i to x.
  • You may repeat this procedure as many times as needed.

Return true if it is possible to construct the target array from arr, otherwise, return false.

Solution 1

递归,每次寻找到数组中最大的数字的下标maxIndex,并对整个数组加和。
当数组中出现小于1的数时,不成立,返回false。
当数组加和等于数组长度时,返回true。

记录剩余的数字others,如果没有剩余数字,则返回false。
将target[maxIndex]减去others,因此每次翻倍,快速逼近。
当小于0时,则还原到上一个target[maxIndex]。

递归更改后的数组。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public boolean isPossible(int[] target) {
int maxIndex = 0, sum = 0;
for(int i = 0; i < target.length; i++){
if(target[i] <= 0) return false; //数组中出现小于1的数,则不成立,返回false
if(target[maxIndex] < target[i]) maxIndex = i;
sum += target[i];
}
if(sum == target.length) return true; //加和等于长度,则数组内全部为1,返回true
int others = sum - target[maxIndex];
if(others == 0) return false; //没有其他值时返回false
target[maxIndex] -= others;
int n = 1;
while(target[maxIndex] > others){
target[maxIndex] -= n * others;
if(target[maxIndex] <= 0){
target[maxIndex] += n * others;
break;
}
n*=2; //因子每次翻倍,快速逼近
}
return isPossible(target);
}
}

Solution 2

优先级队列, 大根堆。
每次挤出队列里最大的数字max。

如果max的值为1,则返回true。

计算加和和新的值,并更新sum。
如果最大的数字max小于0,或者剩余的sum小于0,则返回false。

当max仍然大于剩下的数字时,继续做减法。采用因数翻倍,快速接近目标值。
如果max小于0,则恢复到上一个值,并添加到优先级队列中。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Solution {
public boolean isPossible(int[] target) {
PriorityQueue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
int sum = 0;
for(int num : target){
pq.offer(num);
sum+=num;
}
while(true){
int max = pq.poll();
if(max == 1) return true;

sum -= max;
max = max - sum;
if(sum <= 0 || max <= 0) return false;

int n = 1;
while(max > sum){
max -= n * sum;
if(max <= 0){
max += n * sum;
break;
}
n*=2;
}
sum += max;
pq.offer(max);
}
}
}

2302. Count Subarrays With Score Less Than K

Question

The score of an array is defined as the product of its sum and its length.

  • For example, the score of [1, 2, 3, 4, 5] is (1 + 2 + 3 + 4 + 5) * 5 = 75.

Given a positive integer array nums and an integer k, return the number of non-empty subarrays of nums whose score is strictly less than k.

A subarray is a contiguous sequence of elements within an array.

Solution

第一次在contest中做出hard题目,而且还是超过100%,庆祝一下!(不过因为前一道题做的太久没提交上去……

滑动窗口

数组内全部为正整数,当选择的子数组的尺寸增加时,其乘积是单调递增的。因此可以采用滑动窗口,在循环时维护窗口内数字的和sum和当前的乘积product。

每次将一个新的右侧元素滑入窗口,更新窗口内的sum值,并计算product值。当当前product大于k时,则将左侧的元素滑出窗口,并更新sum和product值。

调整完窗口尺寸后,由于新的right位置可以和前面的每一个子数组组成一个新的数组,因此将count加上当前的left到right的个数即可。

循环结束后返回count。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public long countSubarrays(int[] nums, long k) {
long count = 0, sum = 0;
int left = 0, right = 0;

while(right < nums.length){
sum += nums[right]; //右侧滑入窗口
long product = sum * (right - left + 1);

while(product >= k){ //当乘积大于k时,左侧滑出窗口
sum -= nums[left];
left++;
product = sum * (right - left + 1);
}
count += right - left + 1; //计算新的right位置可组成的新组合
right++;
}
return count;
}
}