[LeetCode] Minimum Operations to Make Subarray Elements Equal

3422. Minimum Operations to Make Subarray Elements Equal

You are given an integer array nums and an integer k. You can perform the following operation any number of times:

  • Increase or decrease any element of nums by 1.

Return the minimum number of operations required to ensure that at least one

subarray

of size k in nums has all elements equal.

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package main

import (
"math"
"sort"
)

type Seg struct {
mi, ma, sum, cnt int
left, right *Seg
}

func NewSeg(A []int, l, r int) *Seg {
seg := &Seg{mi: A[l], ma: A[r], sum: 0, cnt: 0}
if l != r {
m := (l + r) / 2
seg.left = NewSeg(A, l, m)
seg.right = NewSeg(A, m+1, r)
}
return seg
}

func (seg *Seg) query(l, r int) (int, int) {
if l <= seg.mi && seg.ma <= r {
return seg.sum, seg.cnt
}
if l > seg.ma || r < seg.mi {
return 0, 0
}
lsum, lcnt := seg.left.query(l, r)
rsum, rcnt := seg.right.query(l, r)
return lsum + rsum, lcnt + rcnt
}

func (seg *Seg) update(x, op int) {
if seg.mi <= x && x <= seg.ma {
seg.sum += x * op
seg.cnt += op
if seg.left != nil {
seg.left.update(x, op)
}
if seg.right != nil {
seg.right.update(x, op)
}
}
}

func (seg *Seg) find(k int) int {
if seg.mi == seg.ma {
return seg.mi
}
if seg.left.cnt >= k {
return seg.left.find(k)
}
return seg.right.find(k - seg.left.cnt)
}


func minOperations(nums []int, k int) int64 {
S := append([]int{}, nums...)
sort.Ints(S)
S = unique(S)
seg := NewSeg(S, 0, len(S)-1)
res := int64(math.MaxInt64)

for i := 0; i < len(nums); i++ {
seg.update(nums[i], 1)
if i+1 >= k {
if i >= k {
seg.update(nums[i-k], -1)
}
m := seg.find((k + 1) / 2)
lsum, lcnt := seg.query(math.MinInt, m-1)
rsum, rcnt := seg.query(m+1, math.MaxInt)
res = min(res, int64(lcnt)*int64(m)-int64(lsum)+int64(rsum)-int64(rcnt)*int64(m))
}
}
return res
}

func unique(arr []int) []int {
m := make(map[int]bool)
res := []int{}
for _, v := range arr {
if !m[v] {
res = append(res, v)
m[v] = true
}
}
return res
}

func min(a, b int64) int64 {
if a < b {
return a
}
return b
}
Author: Song Hayoung
Link: https://songhayoung.github.io/2025/01/18/PS/LeetCode/minimum-operations-to-make-subarray-elements-equal/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.