Skip to content

Commit bfa81dd

Browse files
committed
feat: add solutions to lc problem: No.0659
No.0659.Split Array into Consecutive Subsequences
1 parent e3f523d commit bfa81dd

File tree

8 files changed

+293
-6
lines changed

8 files changed

+293
-6
lines changed

solution/0600-0699/0659.Split Array into Consecutive Subsequences/README.md

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,129 @@
5353

5454
<!-- 这里可写通用的实现逻辑 -->
5555

56+
**方法一:哈希表 + 优先队列(小根堆)**
57+
58+
由于题目中的子序列是由连续整数组成的,因此,只要知道子序列的最后一个数以及子序列的长度,就能够确定子序列。
59+
60+
我们可以使用哈希表存储每个子序列的最后一个数,使用优先队列存储当前数作为子序列的末尾时,子序列的长度。我们要优先选择长度较短的子序列,因此使用小根堆。
61+
62+
遍历数组 `nums`,对于当前遍历到的数 `num`,如果 `num` 不能加入到任何子序列中,那么我们就创建一个新的子序列,长度为 1;否则,我们就将 `num` 加入到某个子序列中,具体的子序列是哪个呢?我们可以从 `num - 1` 对应的子序列中取出一个长度最短的子序列,将 `num` 加入到该子序列中,然后将该子序列的最后一个数更新为 `num`,同时将该子序列的长度加 1。
63+
64+
如果我们遍历完数组 `nums`,优先队列中所有的子序列的长度都不小于 3,那么我们就可以将数组 `nums` 分割成若干个子序列,否则,我们就无法将数组 `nums` 分割成若干个子序列。
65+
66+
时间复杂度 $O(n\log n)$,其中 $n$ 是数组 `nums` 的长度。空间复杂度 $O(n)$。
67+
5668
<!-- tabs:start -->
5769

5870
### **Python3**
5971

6072
<!-- 这里可写当前语言的特殊实现逻辑 -->
6173

6274
```python
63-
75+
class Solution:
76+
def isPossible(self, nums: List[int]) -> bool:
77+
d = defaultdict(list)
78+
for v in nums:
79+
if h := d[v - 1]:
80+
heappush(d[v], heappop(h) + 1)
81+
else:
82+
heappush(d[v], 1)
83+
return all(not v or v and v[0] > 2 for v in d.values())
6484
```
6585

6686
### **Java**
6787

6888
<!-- 这里可写当前语言的特殊实现逻辑 -->
6989

7090
```java
91+
class Solution {
92+
public boolean isPossible(int[] nums) {
93+
Map<Integer, PriorityQueue<Integer>> d = new HashMap<>();
94+
for (int v : nums) {
95+
if (d.containsKey(v - 1)) {
96+
var q = d.get(v - 1);
97+
d.computeIfAbsent(v, k -> new PriorityQueue<>()).offer(q.poll() + 1);
98+
if (q.isEmpty()) {
99+
d.remove(v - 1);
100+
}
101+
} else {
102+
d.computeIfAbsent(v, k -> new PriorityQueue<>()).offer(1);
103+
}
104+
}
105+
for (var v : d.values()) {
106+
if (v.peek() < 3) {
107+
return false;
108+
}
109+
}
110+
return true;
111+
}
112+
}
113+
```
114+
115+
### **C++**
116+
117+
```cpp
118+
class Solution {
119+
public:
120+
bool isPossible(vector<int>& nums) {
121+
unordered_map<int, priority_queue<int, vector<int>, greater<int>>> d;
122+
for (int v : nums) {
123+
if (d.count(v - 1)) {
124+
auto& q = d[v - 1];
125+
d[v].push(q.top() + 1);
126+
q.pop();
127+
if (q.empty()) {
128+
d.erase(v - 1);
129+
}
130+
} else {
131+
d[v].push(1);
132+
}
133+
}
134+
for (auto& [_, v] : d) {
135+
if (v.top() < 3) {
136+
return false;
137+
}
138+
}
139+
return true;
140+
}
141+
};
142+
```
71143
144+
### **Go**
145+
146+
```go
147+
func isPossible(nums []int) bool {
148+
d := map[int]*hp{}
149+
for _, v := range nums {
150+
if d[v] == nil {
151+
d[v] = new(hp)
152+
}
153+
if h := d[v-1]; h != nil {
154+
heap.Push(d[v], heap.Pop(h).(int)+1)
155+
if h.Len() == 0 {
156+
delete(d, v-1)
157+
}
158+
} else {
159+
heap.Push(d[v], 1)
160+
}
161+
}
162+
for _, q := range d {
163+
if q.IntSlice[0] < 3 {
164+
return false
165+
}
166+
}
167+
return true
168+
}
169+
170+
type hp struct{ sort.IntSlice }
171+
172+
func (h *hp) Push(v interface{}) { h.IntSlice = append(h.IntSlice, v.(int)) }
173+
func (h *hp) Pop() interface{} {
174+
a := h.IntSlice
175+
v := a[len(a)-1]
176+
h.IntSlice = a[:len(a)-1]
177+
return v
178+
}
72179
```
73180

74181
### **...**

solution/0600-0699/0659.Split Array into Consecutive Subsequences/README_EN.md

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,108 @@
6262
### **Python3**
6363

6464
```python
65-
65+
class Solution:
66+
def isPossible(self, nums: List[int]) -> bool:
67+
d = defaultdict(list)
68+
for v in nums:
69+
if h := d[v - 1]:
70+
heappush(d[v], heappop(h) + 1)
71+
else:
72+
heappush(d[v], 1)
73+
return all(not v or v and v[0] > 2 for v in d.values())
6674
```
6775

6876
### **Java**
6977

7078
```java
79+
class Solution {
80+
public boolean isPossible(int[] nums) {
81+
Map<Integer, PriorityQueue<Integer>> d = new HashMap<>();
82+
for (int v : nums) {
83+
if (d.containsKey(v - 1)) {
84+
var q = d.get(v - 1);
85+
d.computeIfAbsent(v, k -> new PriorityQueue<>()).offer(q.poll() + 1);
86+
if (q.isEmpty()) {
87+
d.remove(v - 1);
88+
}
89+
} else {
90+
d.computeIfAbsent(v, k -> new PriorityQueue<>()).offer(1);
91+
}
92+
}
93+
for (var v : d.values()) {
94+
if (v.peek() < 3) {
95+
return false;
96+
}
97+
}
98+
return true;
99+
}
100+
}
101+
```
102+
103+
### **C++**
104+
105+
```cpp
106+
class Solution {
107+
public:
108+
bool isPossible(vector<int>& nums) {
109+
unordered_map<int, priority_queue<int, vector<int>, greater<int>>> d;
110+
for (int v : nums) {
111+
if (d.count(v - 1)) {
112+
auto& q = d[v - 1];
113+
d[v].push(q.top() + 1);
114+
q.pop();
115+
if (q.empty()) {
116+
d.erase(v - 1);
117+
}
118+
} else {
119+
d[v].push(1);
120+
}
121+
}
122+
for (auto& [_, v] : d) {
123+
if (v.top() < 3) {
124+
return false;
125+
}
126+
}
127+
return true;
128+
}
129+
};
130+
```
71131
132+
### **Go**
133+
134+
```go
135+
func isPossible(nums []int) bool {
136+
d := map[int]*hp{}
137+
for _, v := range nums {
138+
if d[v] == nil {
139+
d[v] = new(hp)
140+
}
141+
if h := d[v-1]; h != nil {
142+
heap.Push(d[v], heap.Pop(h).(int)+1)
143+
if h.Len() == 0 {
144+
delete(d, v-1)
145+
}
146+
} else {
147+
heap.Push(d[v], 1)
148+
}
149+
}
150+
for _, q := range d {
151+
if q.IntSlice[0] < 3 {
152+
return false
153+
}
154+
}
155+
return true
156+
}
157+
158+
type hp struct{ sort.IntSlice }
159+
160+
func (h *hp) Push(v interface{}) { h.IntSlice = append(h.IntSlice, v.(int)) }
161+
func (h *hp) Pop() interface{} {
162+
a := h.IntSlice
163+
v := a[len(a)-1]
164+
h.IntSlice = a[:len(a)-1]
165+
return v
166+
}
72167
```
73168

74169
### **...**
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class Solution {
2+
public:
3+
bool isPossible(vector<int>& nums) {
4+
unordered_map<int, priority_queue<int, vector<int>, greater<int>>> d;
5+
for (int v : nums) {
6+
if (d.count(v - 1)) {
7+
auto& q = d[v - 1];
8+
d[v].push(q.top() + 1);
9+
q.pop();
10+
if (q.empty()) {
11+
d.erase(v - 1);
12+
}
13+
} else {
14+
d[v].push(1);
15+
}
16+
}
17+
for (auto& [_, v] : d) {
18+
if (v.top() < 3) {
19+
return false;
20+
}
21+
}
22+
return true;
23+
}
24+
};
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
func isPossible(nums []int) bool {
2+
d := map[int]*hp{}
3+
for _, v := range nums {
4+
if d[v] == nil {
5+
d[v] = new(hp)
6+
}
7+
if h := d[v-1]; h != nil {
8+
heap.Push(d[v], heap.Pop(h).(int)+1)
9+
if h.Len() == 0 {
10+
delete(d, v-1)
11+
}
12+
} else {
13+
heap.Push(d[v], 1)
14+
}
15+
}
16+
for _, q := range d {
17+
if q.IntSlice[0] < 3 {
18+
return false
19+
}
20+
}
21+
return true
22+
}
23+
24+
type hp struct{ sort.IntSlice }
25+
26+
func (h *hp) Push(v interface{}) { h.IntSlice = append(h.IntSlice, v.(int)) }
27+
func (h *hp) Pop() interface{} {
28+
a := h.IntSlice
29+
v := a[len(a)-1]
30+
h.IntSlice = a[:len(a)-1]
31+
return v
32+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class Solution {
2+
public boolean isPossible(int[] nums) {
3+
Map<Integer, PriorityQueue<Integer>> d = new HashMap<>();
4+
for (int v : nums) {
5+
if (d.containsKey(v - 1)) {
6+
var q = d.get(v - 1);
7+
d.computeIfAbsent(v, k -> new PriorityQueue<>()).offer(q.poll() + 1);
8+
if (q.isEmpty()) {
9+
d.remove(v - 1);
10+
}
11+
} else {
12+
d.computeIfAbsent(v, k -> new PriorityQueue<>()).offer(1);
13+
}
14+
}
15+
for (var v : d.values()) {
16+
if (v.peek() < 3) {
17+
return false;
18+
}
19+
}
20+
return true;
21+
}
22+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class Solution:
2+
def isPossible(self, nums: List[int]) -> bool:
3+
d = defaultdict(list)
4+
for v in nums:
5+
if h := d[v - 1]:
6+
heappush(d[v], heappop(h) + 1)
7+
else:
8+
heappush(d[v], 1)
9+
return all(not v or v and v[0] > 2 for v in d.values())

solution/0600-0699/0698.Partition to K Equal Sum Subsets/README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@
4747

4848
如果能将所有元素都加入到 `cur` 中,说明可以划分为 $k$ 个子集,返回 `true`
4949

50-
时间复杂度 $O(k^n)$,其中 $n$ 表示数组 $nums$ 的长度。每个数可以被加入到 $k$ 个子集中,因此,时间复杂度为 $O(k^n)$。
51-
5250
**方法二:状态压缩 + 记忆化搜索**
5351

5452
与方法一相同,我们依然先判断数组 `nums` 是否有可能被划分为 $k$ 个子集。如果不能被 $k$ 整除,直接返回 `false`
@@ -116,7 +114,7 @@ class Solution:
116114
s, mod = divmod(sum(nums), k)
117115
if mod:
118116
return False
119-
nums.sort(reverse=True)
117+
nums.sort()
120118
mask = (1 << len(nums)) - 1
121119
return dfs(0, 0)
122120
```

solution/0600-0699/0698.Partition to K Equal Sum Subsets/README_EN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class Solution:
7979
s, mod = divmod(sum(nums), k)
8080
if mod:
8181
return False
82-
nums.sort(reverse=True)
82+
nums.sort()
8383
mask = (1 << len(nums)) - 1
8484
return dfs(0, 0)
8585
```

0 commit comments

Comments
 (0)