Skip to content

Commit 99425ce

Browse files
authored
feat: update solutions to lc problem: No.1296 (doocs#3630)
No.1296.Divide Array in Sets of K Consecutive Numbers
1 parent b335300 commit 99425ce

File tree

5 files changed

+67
-49
lines changed

5 files changed

+67
-49
lines changed

solution/1200-1299/1296.Divide Array in Sets of K Consecutive Numbers/README.md

+20-18
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@ tags:
7171

7272
### 方法一:哈希表 + 排序
7373

74-
我们先用哈希表 `cnt` 统计数组 `nums` 中每个数字出现的次数,然后对数组 `nums` 进行排序。
74+
我们用一个哈希表 $\textit{cnt}$ 统计数组 $\textit{nums}$ 中每个数字出现的次数,然后对数组 $\textit{nums}$ 进行排序。
7575

76-
接下来,我们遍历数组 `nums`,对于数组中的每个数字 $v$,如果 $v$ 在哈希表 `cnt` 中出现的次数不为 $0$,则我们枚举 $v$ 到 $v+k-1$ 的每个数字,如果这些数字在哈希表 `cnt` 中出现的次数都不为 $0$,则我们将这些数字的出现次数减 $1$,如果减 $1$ 后这些数字的出现次数为 $0$,则我们在哈希表 `cnt` 中删除这些数字。否则说明无法将数组划分成若干个长度为 $k$ 的子数组,返回 `false`。如果可以将数组划分成若干个长度为 $k$ 的子数组,则遍历结束后返回 `true`
76+
接下来,我们遍历数组 $\textit{nums}$,对于数组中的每个数字 $v$,如果 $v$ 在哈希表 $\textit{cnt}$ 中出现的次数不为 $0$,则我们枚举 $v$ 到 $v+k-1$ 的每个数字,如果这些数字在哈希表 $\textit{cnt}$ 中出现的次数都不为 $0$,则我们将这些数字的出现次数减 $1$,如果减 $1$ 后这些数字的出现次数为 $0$,则我们在哈希表 $\textit{cnt}$ 中删除这些数字。否则说明无法将数组划分成若干个长度为 $k$ 的子数组,返回 `false`。如果可以将数组划分成若干个长度为 $k$ 的子数组,则遍历结束后返回 `true`
7777

78-
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 `nums` 的长度。
78+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $\textit{nums}$ 的长度。
7979

8080
<!-- tabs:start -->
8181

@@ -103,7 +103,7 @@ class Solution {
103103
public boolean isPossibleDivide(int[] nums, int k) {
104104
Map<Integer, Integer> cnt = new HashMap<>();
105105
for (int v : nums) {
106-
cnt.put(v, cnt.getOrDefault(v, 0) + 1);
106+
cnt.merge(v, 1, Integer::sum);
107107
}
108108
Arrays.sort(nums);
109109
for (int v : nums) {
@@ -112,8 +112,7 @@ class Solution {
112112
if (!cnt.containsKey(x)) {
113113
return false;
114114
}
115-
cnt.put(x, cnt.get(x) - 1);
116-
if (cnt.get(x) == 0) {
115+
if (cnt.merge(x, -1, Integer::sum) == 0) {
117116
cnt.remove(x);
118117
}
119118
}
@@ -184,11 +183,11 @@ func isPossibleDivide(nums []int, k int) bool {
184183

185184
### 方法二:有序集合
186185

187-
我们也可以使用有序集合统计数组 `nums` 中每个数字出现的次数。
186+
我们也可以使用有序集合统计数组 $\textit{nums}$ 中每个数字出现的次数。
188187

189188
接下来,循环取出有序集合中的最小值 $v$,然后枚举 $v$ 到 $v+k-1$ 的每个数字,如果这些数字在有序集合中出现的次数都不为 $0$,则我们将这些数字的出现次数减 $1$,如果出现次数减 $1$ 后为 $0$,则将该数字从有序集合中删除,否则说明无法将数组划分成若干个长度为 $k$ 的子数组,返回 `false`。如果可以将数组划分成若干个长度为 $k$ 的子数组,则遍历结束后返回 `true`
190189

191-
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 `nums` 的长度。
190+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $\textit{nums}$ 的长度。
192191

193192
<!-- tabs:start -->
194193

@@ -230,18 +229,16 @@ class Solution {
230229
}
231230
TreeMap<Integer, Integer> tm = new TreeMap<>();
232231
for (int h : nums) {
233-
tm.put(h, tm.getOrDefault(h, 0) + 1);
232+
tm.merge(h, 1, Integer::sum);
234233
}
235234
while (!tm.isEmpty()) {
236235
int v = tm.firstKey();
237236
for (int i = v; i < v + k; ++i) {
238237
if (!tm.containsKey(i)) {
239238
return false;
240239
}
241-
if (tm.get(i) == 1) {
240+
if (tm.merge(i, -1, Integer::sum) == 0) {
242241
tm.remove(i);
243-
} else {
244-
tm.put(i, tm.get(i) - 1);
245242
}
246243
}
247244
}
@@ -256,17 +253,22 @@ class Solution {
256253
class Solution {
257254
public:
258255
bool isPossibleDivide(vector<int>& nums, int k) {
259-
if (nums.size() % k != 0) return false;
256+
if (nums.size() % k) {
257+
return false;
258+
}
260259
map<int, int> mp;
261-
for (int& h : nums) mp[h] += 1;
260+
for (int& h : nums) {
261+
mp[h] += 1;
262+
}
262263
while (!mp.empty()) {
263264
int v = mp.begin()->first;
264265
for (int i = v; i < v + k; ++i) {
265-
if (!mp.count(i)) return false;
266-
if (mp[i] == 1)
266+
if (!mp.contains(i)) {
267+
return false;
268+
}
269+
if (--mp[i] == 0) {
267270
mp.erase(i);
268-
else
269-
mp[i] -= 1;
271+
}
270272
}
271273
}
272274
return true;

solution/1200-1299/1296.Divide Array in Sets of K Consecutive Numbers/README_EN.md

+29-15
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,13 @@ tags:
6767

6868
<!-- solution:start -->
6969

70-
### Solution 1
70+
### Solution 1: Hash Table + Sorting
71+
72+
We use a hash table $\textit{cnt}$ to count the occurrences of each number in the array $\textit{nums}$, and then sort the array $\textit{nums}$.
73+
74+
Next, we traverse the array $\textit{nums}$. For each number $v$ in the array, if the count of $v$ in the hash table $\textit{cnt}$ is not zero, we enumerate each number from $v$ to $v+k-1$. If the counts of these numbers in the hash table $\textit{cnt}$ are all non-zero, we decrement the counts of these numbers by 1. If the count becomes zero after decrementing, we remove these numbers from the hash table $\textit{cnt}$. Otherwise, it means we cannot divide the array into several subarrays of length $k$, and we return `false`. If we can divide the array into several subarrays of length $k$, we return `true` after the traversal.
75+
76+
The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $\textit{nums}$.
7177

7278
<!-- tabs:start -->
7379

@@ -95,7 +101,7 @@ class Solution {
95101
public boolean isPossibleDivide(int[] nums, int k) {
96102
Map<Integer, Integer> cnt = new HashMap<>();
97103
for (int v : nums) {
98-
cnt.put(v, cnt.getOrDefault(v, 0) + 1);
104+
cnt.merge(v, 1, Integer::sum);
99105
}
100106
Arrays.sort(nums);
101107
for (int v : nums) {
@@ -104,8 +110,7 @@ class Solution {
104110
if (!cnt.containsKey(x)) {
105111
return false;
106112
}
107-
cnt.put(x, cnt.get(x) - 1);
108-
if (cnt.get(x) == 0) {
113+
if (cnt.merge(x, -1, Integer::sum) == 0) {
109114
cnt.remove(x);
110115
}
111116
}
@@ -174,7 +179,13 @@ func isPossibleDivide(nums []int, k int) bool {
174179

175180
<!-- solution:start -->
176181

177-
### Solution 2
182+
### Solution 1: Ordered Set
183+
184+
We can also use an ordered set to count the occurrences of each number in the array $\textit{nums}$.
185+
186+
Next, we loop to extract the minimum value $v$ from the ordered set, then enumerate each number from $v$ to $v+k-1$. If the occurrences of these numbers in the ordered set are all non-zero, we decrement the occurrence count of these numbers by 1. If the occurrence count becomes 0 after decrementing, we remove the number from the ordered set. Otherwise, it means we cannot divide the array into several subarrays of length $k$, and we return `false`. If we can divide the array into several subarrays of length $k$, we return `true` after the traversal.
187+
188+
The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $\textit{nums}$.
178189

179190
<!-- tabs:start -->
180191

@@ -216,18 +227,16 @@ class Solution {
216227
}
217228
TreeMap<Integer, Integer> tm = new TreeMap<>();
218229
for (int h : nums) {
219-
tm.put(h, tm.getOrDefault(h, 0) + 1);
230+
tm.merge(h, 1, Integer::sum);
220231
}
221232
while (!tm.isEmpty()) {
222233
int v = tm.firstKey();
223234
for (int i = v; i < v + k; ++i) {
224235
if (!tm.containsKey(i)) {
225236
return false;
226237
}
227-
if (tm.get(i) == 1) {
238+
if (tm.merge(i, -1, Integer::sum) == 0) {
228239
tm.remove(i);
229-
} else {
230-
tm.put(i, tm.get(i) - 1);
231240
}
232241
}
233242
}
@@ -242,17 +251,22 @@ class Solution {
242251
class Solution {
243252
public:
244253
bool isPossibleDivide(vector<int>& nums, int k) {
245-
if (nums.size() % k != 0) return false;
254+
if (nums.size() % k) {
255+
return false;
256+
}
246257
map<int, int> mp;
247-
for (int& h : nums) mp[h] += 1;
258+
for (int& h : nums) {
259+
mp[h] += 1;
260+
}
248261
while (!mp.empty()) {
249262
int v = mp.begin()->first;
250263
for (int i = v; i < v + k; ++i) {
251-
if (!mp.count(i)) return false;
252-
if (mp[i] == 1)
264+
if (!mp.contains(i)) {
265+
return false;
266+
}
267+
if (--mp[i] == 0) {
253268
mp.erase(i);
254-
else
255-
mp[i] -= 1;
269+
}
256270
}
257271
}
258272
return true;

solution/1200-1299/1296.Divide Array in Sets of K Consecutive Numbers/Solution.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ class Solution {
22
public boolean isPossibleDivide(int[] nums, int k) {
33
Map<Integer, Integer> cnt = new HashMap<>();
44
for (int v : nums) {
5-
cnt.put(v, cnt.getOrDefault(v, 0) + 1);
5+
cnt.merge(v, 1, Integer::sum);
66
}
77
Arrays.sort(nums);
88
for (int v : nums) {
@@ -11,13 +11,12 @@ public boolean isPossibleDivide(int[] nums, int k) {
1111
if (!cnt.containsKey(x)) {
1212
return false;
1313
}
14-
cnt.put(x, cnt.get(x) - 1);
15-
if (cnt.get(x) == 0) {
14+
if (cnt.merge(x, -1, Integer::sum) == 0) {
1615
cnt.remove(x);
1716
}
1817
}
1918
}
2019
}
2120
return true;
2221
}
23-
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
class Solution {
22
public:
33
bool isPossibleDivide(vector<int>& nums, int k) {
4-
if (nums.size() % k != 0) return false;
4+
if (nums.size() % k) {
5+
return false;
6+
}
57
map<int, int> mp;
6-
for (int& h : nums) mp[h] += 1;
8+
for (int& h : nums) {
9+
mp[h] += 1;
10+
}
711
while (!mp.empty()) {
812
int v = mp.begin()->first;
913
for (int i = v; i < v + k; ++i) {
10-
if (!mp.count(i)) return false;
11-
if (mp[i] == 1)
14+
if (!mp.contains(i)) {
15+
return false;
16+
}
17+
if (--mp[i] == 0) {
1218
mp.erase(i);
13-
else
14-
mp[i] -= 1;
19+
}
1520
}
1621
}
1722
return true;
1823
}
19-
};
24+
};

solution/1200-1299/1296.Divide Array in Sets of K Consecutive Numbers/Solution2.java

+3-5
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,19 @@ public boolean isPossibleDivide(int[] nums, int k) {
55
}
66
TreeMap<Integer, Integer> tm = new TreeMap<>();
77
for (int h : nums) {
8-
tm.put(h, tm.getOrDefault(h, 0) + 1);
8+
tm.merge(h, 1, Integer::sum);
99
}
1010
while (!tm.isEmpty()) {
1111
int v = tm.firstKey();
1212
for (int i = v; i < v + k; ++i) {
1313
if (!tm.containsKey(i)) {
1414
return false;
1515
}
16-
if (tm.get(i) == 1) {
16+
if (tm.merge(i, -1, Integer::sum) == 0) {
1717
tm.remove(i);
18-
} else {
19-
tm.put(i, tm.get(i) - 1);
2018
}
2119
}
2220
}
2321
return true;
2422
}
25-
}
23+
}

0 commit comments

Comments
 (0)