50
50
51
51
## 解法
52
52
53
- ### 方法一
53
+ ### 方法一:前缀和 + 哈希表
54
+
55
+ 我们用一个哈希表 $p$ 记录 $nums[ i] $ 的前缀数组 $nums[ 0..i-1] $ 的和 $s$,如果有多个相同的 $nums[ i] $,我们只保留最小的 $s$。初始时,我们将 $p[ nums[ 0]] $ 设为 $0$。另外,我们用一个变量 $s$ 记录当前的前缀和,初始时 $s = 0$。初始化答案 $ans$ 为 $-\infty$。
56
+
57
+ 接下来,我们枚举 $nums[ i] $,并且维护一个变量 $s$ 表示 $nums[ 0..i] $ 的和。如果 $nums[ i] - k$ 在 $p$ 中,那么我们就找到了一个好子数组,将答案更新为 $ans = \max(ans, s - p[ nums[ i] - k] )$。同理,如果 $nums[ i] + k$ 在 $p$ 中,那么我们也找到了一个好子数组,将答案更新为 $ans = \max(ans, s - p[ nums[ i] + k] )$。然后,如果 $i + 1 \lt n$ 并且 $nums[ i + 1] $ 不在 $p$ 中,或者 $p[ nums[ i + 1]] \gt s$,我们就将 $p[ nums[ i + 1]] $ 设为 $s$。
58
+
59
+ 最后,如果 $ans = -\infty$,那么我们返回 $0$,否则返回 $ans$。
60
+
61
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。
54
62
55
63
<!-- tabs:start -->
56
64
57
65
``` python
58
66
class Solution :
59
67
def maximumSubarraySum (self , nums : List[int ], k : int ) -> int :
60
- p = {}
61
- r = float (' -inf' )
62
- p[nums[0 ]] = 0
63
- s = 0
64
- n = len (nums)
65
- for i in range (n):
66
- s += nums[i]
67
- if nums[i] - k in p:
68
- r = max (r, s - p[nums[i] - k])
69
- if nums[i] + k in p:
70
- r = max (r, s - p[nums[i] + k])
71
- if i + 1 == n:
72
- break
73
- if nums[i + 1 ] not in p or p[nums[i + 1 ]] > s:
68
+ ans = - inf
69
+ p = {nums[0 ]: 0 }
70
+ s, n = 0 , len (nums)
71
+ for i, x in enumerate (nums):
72
+ s += x
73
+ if x - k in p:
74
+ ans = max (ans, s - p[x - k])
75
+ if x + k in p:
76
+ ans = max (ans, s - p[x + k])
77
+ if i + 1 < n and (nums[i + 1 ] not in p or p[nums[i + 1 ]] > s):
74
78
p[nums[i + 1 ]] = s
75
- return r if r != float ( ' -inf' ) else 0
79
+ return 0 if ans == - inf else ans
76
80
```
77
81
78
82
``` java
79
83
class Solution {
80
84
public long maximumSubarraySum (int [] nums , int k ) {
81
- HashMap<Integer , Long > p = new HashMap<> ();
82
- long r = Long . MIN_VALUE ;
85
+ Map<Integer , Long > p = new HashMap<> ();
83
86
p. put(nums[0 ], 0L );
84
87
long s = 0 ;
85
88
int n = nums. length;
86
- for (int i = 0 ;; ++ i) {
89
+ long ans = Long . MIN_VALUE ;
90
+ for (int i = 0 ; i < n; ++ i) {
87
91
s += nums[i];
88
92
if (p. containsKey(nums[i] - k)) {
89
- r = Math . max(r , s - p. get(nums[i] - k));
93
+ ans = Math . max(ans , s - p. get(nums[i] - k));
90
94
}
91
95
if (p. containsKey(nums[i] + k)) {
92
- r = Math . max(r , s - p. get(nums[i] + k));
96
+ ans = Math . max(ans , s - p. get(nums[i] + k));
93
97
}
94
- if (i + 1 == n) break ;
95
- if (! p. containsKey(nums[i + 1 ]) || p. get(nums[i + 1 ]) > s) {
98
+ if (i + 1 < n && (! p. containsKey(nums[i + 1 ]) || p. get(nums[i + 1 ]) > s)) {
96
99
p. put(nums[i + 1 ], s);
97
100
}
98
101
}
99
- return r == Long . MIN_VALUE ? 0 : r ;
102
+ return ans == Long . MIN_VALUE ? 0 : ans ;
100
103
}
101
104
}
102
105
```
@@ -106,85 +109,106 @@ class Solution {
106
109
public:
107
110
long long maximumSubarraySum(vector<int >& nums, int k) {
108
111
unordered_map<int, long long> p;
109
- long long r = LONG_LONG_MIN;
110
112
p[ nums[ 0]] = 0;
111
113
long long s = 0;
112
114
const int n = nums.size();
115
+ long long ans = LONG_LONG_MIN;
113
116
for (int i = 0;; ++i) {
114
117
s += nums[ i] ;
115
- auto t = p.find(nums[ i] - k);
116
- if (t != p.end()) {
117
- r = max(r, s - t->second);
118
+ auto it = p.find(nums[ i] - k);
119
+ if (it != p.end()) {
120
+ ans = max(ans, s - it->second);
121
+ }
122
+ it = p.find(nums[ i] + k);
123
+ if (it != p.end()) {
124
+ ans = max(ans, s - it->second);
118
125
}
119
- t = p.find(nums[ i] + k);
120
- if (t != p.end()) {
121
- r = max(r, s - t->second);
126
+ if (i + 1 == n) {
127
+ break;
122
128
}
123
- if (i + 1 == n)
124
- break;
125
- t = p.find(nums[ i + 1] );
126
- if (t == p.end() || t->second > s) {
129
+ it = p.find(nums[ i + 1] );
130
+ if (it == p.end() || it->second > s) {
127
131
p[ nums[ i + 1]] = s;
128
132
}
129
133
}
130
- return r == LONG_LONG_MIN ? 0 : r ;
134
+ return ans == LONG_LONG_MIN ? 0 : ans ;
131
135
}
132
136
};
133
137
```
134
138
135
139
```go
136
140
func maximumSubarraySum(nums []int, k int) int64 {
137
- p := make(map[int]int64)
138
- var r int64 = math.MinInt64
139
- p[nums[0]] = 0
140
- var s int64 = 0
141
- n := len(nums)
142
- for i := 0; ; i++ {
143
- s += int64(nums[i])
144
- if t, ok := p[nums[i]-k]; ok {
145
- r = max(r, s-t)
146
- }
147
- if t, ok := p[nums[i]+k]; ok {
148
- r = max(r, s-t)
149
- }
150
- if i+1 == n {
151
- break
152
- }
153
- if t, ok := p[nums[i+1]]; !ok || t > s {
154
- p[nums[i+1]] = s
155
- }
156
- }
157
- if r == math.MinInt64 {
158
- return 0
159
- }
160
- return r
141
+ p := map[int]int64{nums[0]: 0}
142
+ var s int64 = 0
143
+ n := len(nums)
144
+ var ans int64 = math.MinInt64
145
+ for i, x := range nums {
146
+ s += int64(x)
147
+ if t, ok := p[nums[i]-k]; ok {
148
+ ans = max(ans, s-t)
149
+ }
150
+ if t, ok := p[nums[i]+k]; ok {
151
+ ans = max(ans, s-t)
152
+ }
153
+ if i+1 == n {
154
+ break
155
+ }
156
+ if t, ok := p[nums[i+1]]; !ok || s < t {
157
+ p[nums[i+1]] = s
158
+ }
159
+ }
160
+ if ans == math.MinInt64 {
161
+ return 0
162
+ }
163
+ return ans
161
164
}
162
165
```
163
166
164
167
``` ts
165
168
function maximumSubarraySum(nums : number [], k : number ): number {
166
169
const p: Map <number , number > = new Map ();
167
- let r: number = Number .MIN_SAFE_INTEGER;
168
170
p .set (nums [0 ], 0 );
171
+ let ans: number = - Infinity ;
169
172
let s: number = 0 ;
170
173
const n: number = nums .length ;
171
- for (let i = 0 ; ; ++ i ) {
174
+ for (let i = 0 ; i < n ; ++ i ) {
172
175
s += nums [i ];
173
- let t: number | undefined = p .get (nums [i ] - k );
174
- if (t !== undefined ) {
175
- r = Math .max (r , s - t );
176
+ if (p .has (nums [i ] - k )) {
177
+ ans = Math .max (ans , s - p .get (nums [i ] - k )! );
176
178
}
177
- t = p .get (nums [i ] + k );
178
- if (t !== undefined ) {
179
- r = Math .max (r , s - t );
179
+ if (p .has (nums [i ] + k )) {
180
+ ans = Math .max (ans , s - p .get (nums [i ] + k )! );
180
181
}
181
- if (i + 1 === n ) break ;
182
- t = p .get (nums [i + 1 ]);
183
- if (t === undefined || t > s ) {
182
+ if (i + 1 < n && (! p .has (nums [i + 1 ]) || p .get (nums [i + 1 ])! > s )) {
184
183
p .set (nums [i + 1 ], s );
185
184
}
186
185
}
187
- return r === Number .MIN_SAFE_INTEGER ? 0 : r ;
186
+ return ans === - Infinity ? 0 : ans ;
187
+ }
188
+ ```
189
+
190
+ ``` cs
191
+ public class Solution {
192
+ public long MaximumSubarraySum (int [] nums , int k ) {
193
+ Dictionary < int , long > p = new Dictionary <int , long >();
194
+ p [nums [0 ]] = 0 L ;
195
+ long s = 0 ;
196
+ int n = nums .Length ;
197
+ long ans = long .MinValue ;
198
+ for (int i = 0 ; i < n ; ++ i ) {
199
+ s += nums [i ];
200
+ if (p .ContainsKey (nums [i ] - k )) {
201
+ ans = Math .Max (ans , s - p [nums [i ] - k ]);
202
+ }
203
+ if (p .ContainsKey (nums [i ] + k )) {
204
+ ans = Math .Max (ans , s - p [nums [i ] + k ]);
205
+ }
206
+ if (i + 1 < n && (! p .ContainsKey (nums [i + 1 ]) || p [nums [i + 1 ]] > s )) {
207
+ p [nums [i + 1 ]] = s ;
208
+ }
209
+ }
210
+ return ans == long .MinValue ? 0 : ans ;
211
+ }
188
212
}
189
213
```
190
214
0 commit comments