Skip to content

Commit b14f316

Browse files
committed
Add solution and test-cases for problem 3321
1 parent 7ce34f6 commit b14f316

File tree

5 files changed

+145
-31
lines changed

5 files changed

+145
-31
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module awesome-golang-algorithm
33
go 1.25
44

55
require (
6+
github.com/emirpasic/gods/v2 v2.0.0-alpha
67
github.com/imroc/req/v3 v3.56.0
78
github.com/stretchr/testify v1.11.1
89
)

go.sum

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUS
33
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
44
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
55
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6+
github.com/emirpasic/gods/v2 v2.0.0-alpha h1:dwFlh8pBg1VMOXWGipNMRt8v96dKAIvBehtCt6OtunU=
7+
github.com/emirpasic/gods/v2 v2.0.0-alpha/go.mod h1:W0y4M2dtBB9U5z3YlghmpuUhiaZT2h6yoeE+C1sCp6A=
68
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
79
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
810
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
@@ -12,8 +14,6 @@ github.com/icholy/digest v1.1.0 h1:HfGg9Irj7i+IX1o1QAmPfIBNu/Q5A5Tu3n/MED9k9H4=
1214
github.com/icholy/digest v1.1.0/go.mod h1:QNrsSGQ5v7v9cReDI0+eyjsXGUoRSUZQHeQ5C4XLa0Y=
1315
github.com/imroc/req/v3 v3.56.0 h1:t6YdqqerYBXhZ9+VjqsQs5wlKxdUNEvsgBhxWc1AEEo=
1416
github.com/imroc/req/v3 v3.56.0/go.mod h1:cUZSooE8hhzFNOrAbdxuemXDQxFXLQTnu3066jr7ZGk=
15-
github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co=
16-
github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0=
1717
github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk=
1818
github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
1919
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
@@ -24,8 +24,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
2424
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
2525
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
2626
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
27-
github.com/quic-go/quic-go v0.56.0 h1:q/TW+OLismmXAehgFLczhCDTYB3bFmua4D9lsNBWxvY=
28-
github.com/quic-go/quic-go v0.56.0/go.mod h1:9gx5KsFQtw2oZ6GZTyh+7YEvOxWCL9WZAepnHxgAo6c=
2927
github.com/quic-go/quic-go v0.57.1 h1:25KAAR9QR8KZrCZRThWMKVAwGoiHIrNbT72ULHTuI10=
3028
github.com/quic-go/quic-go v0.57.1/go.mod h1:ly4QBAjHA2VhdnxhojRsCUOeJwKYg+taDlos92xb1+s=
3129
github.com/refraction-networking/utls v1.8.1 h1:yNY1kapmQU8JeM1sSw2H2asfTIwWxIkrMJI0pRUOCAo=
@@ -38,8 +36,6 @@ github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZ
3836
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
3937
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
4038
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
41-
golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU=
42-
golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc=
4339
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
4440
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
4541
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=

leetcode/3301-3400/3321.Find-X-Sum-of-All-K-Long-Subarrays-II/README.md

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,43 @@
11
# [3321.Find X-Sum of All K-Long Subarrays II][title]
22

3-
> [!WARNING|style:flat]
4-
> This question is temporarily unanswered if you have good ideas. Welcome to [Create Pull Request PR](https://github.com/kylesliu/awesome-golang-algorithm)
5-
63
## Description
4+
You are given an array `nums` of `n` integers and two integers `k` and `x`.
5+
6+
The **x-sum** of an array is calculated by the following procedure:
7+
8+
- Count the occurrences of all elements in the array.
9+
- Keep only the occurrences of the top `x` most frequent elements. If two elements have the same number of occurrences, the element with the **bigger** value is considered more frequent.
10+
- Calculate the sum of the resulting array.
11+
12+
**Note** that if an array has less than x distinct elements, its **x-sum** is the sum of the array.
13+
14+
Return an integer array `answer` of length `n - k + 1` where `answer[i]` is the **x-sum** of the subarray `nums[i..i + k - 1]`.
715

816
**Example 1:**
917

1018
```
11-
Input: a = "11", b = "1"
12-
Output: "100"
13-
```
19+
Input: nums = [1,1,2,2,3,4,2,3], k = 6, x = 2
1420
15-
## 题意
16-
> ...
21+
Output: [6,10,12]
1722
18-
## 题解
23+
Explanation:
1924
20-
### 思路1
21-
> ...
22-
Find X-Sum of All K-Long Subarrays II
23-
```go
25+
For subarray [1, 1, 2, 2, 3, 4], only elements 1 and 2 will be kept in the resulting array. Hence, answer[0] = 1 + 1 + 2 + 2.
26+
For subarray [1, 2, 2, 3, 4, 2], only elements 2 and 4 will be kept in the resulting array. Hence, answer[1] = 2 + 2 + 2 + 4. Note that 4 is kept in the array since it is bigger than 3 and 1 which occur the same number of times.
27+
For subarray [2, 2, 3, 4, 2, 3], only elements 2 and 3 are kept in the resulting array. Hence, answer[2] = 2 + 2 + 2 + 3 + 3.
2428
```
2529

30+
**Example 2:**
31+
32+
```
33+
Input: nums = [3,8,7,8,7,5], k = 2, x = 2
34+
35+
Output: [11,15,15,15,12]
36+
37+
Explanation:
38+
39+
Since k == x, answer[i] is equal to the sum of the subarray nums[i..i + k - 1].
40+
```
2641

2742
## 结语
2843

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,107 @@
11
package Solution
22

3-
func Solution(x bool) bool {
4-
return x
3+
import (
4+
"github.com/emirpasic/gods/v2/trees/redblacktree"
5+
)
6+
7+
func Solution(nums []int, k int, x int) []int64 {
8+
helper := NewHelper(x)
9+
ans := []int64{}
10+
11+
for i := 0; i < len(nums); i++ {
12+
helper.Insert(nums[i])
13+
if i >= k {
14+
helper.Remove(nums[i-k])
15+
}
16+
if i >= k-1 {
17+
ans = append(ans, helper.Get())
18+
}
19+
}
20+
21+
return ans
22+
}
23+
24+
type Helper struct {
25+
x int
26+
result int64
27+
large *redblacktree.Tree[pair, struct{}]
28+
small *redblacktree.Tree[pair, struct{}]
29+
occ map[int]int
30+
}
31+
32+
type pair struct {
33+
freq int
34+
num int
35+
}
36+
37+
func pairComparator(a, b pair) int {
38+
if a.freq != b.freq {
39+
return a.freq - b.freq
40+
}
41+
return a.num - b.num
42+
}
43+
44+
func NewHelper(x int) *Helper {
45+
return &Helper{
46+
x: x,
47+
result: 0,
48+
large: redblacktree.NewWith[pair, struct{}](pairComparator),
49+
small: redblacktree.NewWith[pair, struct{}](pairComparator),
50+
occ: make(map[int]int),
51+
}
52+
}
53+
54+
func (h *Helper) Insert(num int) {
55+
if h.occ[num] > 0 {
56+
h.internalRemove(pair{freq: h.occ[num], num: num})
57+
}
58+
h.occ[num]++
59+
h.internalInsert(pair{freq: h.occ[num], num: num})
60+
}
61+
62+
func (h *Helper) Remove(num int) {
63+
h.internalRemove(pair{freq: h.occ[num], num: num})
64+
h.occ[num]--
65+
if h.occ[num] > 0 {
66+
h.internalInsert(pair{freq: h.occ[num], num: num})
67+
}
68+
}
69+
70+
func (h *Helper) Get() int64 {
71+
return h.result
72+
}
73+
74+
func (h *Helper) internalInsert(p pair) {
75+
if h.large.Size() < h.x {
76+
h.result += int64(p.freq) * int64(p.num)
77+
h.large.Put(p, struct{}{})
78+
} else {
79+
minLarge := h.large.Left().Key
80+
if pairComparator(p, minLarge) > 0 {
81+
h.result += int64(p.freq) * int64(p.num)
82+
h.large.Put(p, struct{}{})
83+
toRemove := h.large.Left().Key
84+
h.result -= int64(toRemove.freq) * int64(toRemove.num)
85+
h.large.Remove(toRemove)
86+
h.small.Put(toRemove, struct{}{})
87+
} else {
88+
h.small.Put(p, struct{}{})
89+
}
90+
}
91+
}
92+
93+
func (h *Helper) internalRemove(p pair) {
94+
if _, found := h.large.Get(p); found {
95+
h.result -= int64(p.freq) * int64(p.num)
96+
h.large.Remove(p)
97+
98+
if h.small.Size() > 0 {
99+
maxSmall := h.small.Right().Key
100+
h.result += int64(maxSmall.freq) * int64(maxSmall.num)
101+
h.small.Remove(maxSmall)
102+
h.large.Put(maxSmall, struct{}{})
103+
}
104+
} else if _, found := h.small.Get(p); found {
105+
h.small.Remove(p)
106+
}
5107
}

leetcode/3301-3400/3321.Find-X-Sum-of-All-K-Long-Subarrays-II/Solution_test.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,30 @@ func TestSolution(t *testing.T) {
1010
// 测试用例
1111
cases := []struct {
1212
name string
13-
inputs bool
14-
expect bool
13+
inputs []int
14+
k, x int
15+
expect []int64
1516
}{
16-
{"TestCase", true, true},
17-
{"TestCase", true, true},
18-
{"TestCase", false, false},
17+
{"TestCase1", []int{1, 1, 2, 2, 3, 4, 2, 3}, 6, 2, []int64{6, 10, 12}},
18+
{"TestCase2", []int{3, 8, 7, 8, 7, 5}, 2, 2, []int64{11, 15, 15, 15, 12}},
1919
}
2020

2121
// 开始测试
2222
for i, c := range cases {
2323
t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) {
24-
got := Solution(c.inputs)
24+
got := Solution(c.inputs, c.k, c.x)
2525
if !reflect.DeepEqual(got, c.expect) {
26-
t.Fatalf("expected: %v, but got: %v, with inputs: %v",
27-
c.expect, got, c.inputs)
26+
t.Fatalf("expected: %v, but got: %v, with inputs: %v %v %v",
27+
c.expect, got, c.inputs, c.k, c.x)
2828
}
2929
})
3030
}
3131
}
3232

33-
// 压力测试
33+
// 压力测试
3434
func BenchmarkSolution(b *testing.B) {
3535
}
3636

37-
// 使用案列
37+
// 使用案列
3838
func ExampleSolution() {
3939
}

0 commit comments

Comments
 (0)