Skip to content

Commit e89ef4f

Browse files
authored
feat: add solutions to lc problem: No.3690 (#4739)
1 parent ea99dcf commit e89ef4f

File tree

6 files changed

+554
-10
lines changed

6 files changed

+554
-10
lines changed

solution/3600-3699/3690.Split and Merge Array Transformation/README.md

Lines changed: 190 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,32 +74,217 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3690.Sp
7474

7575
<!-- solution:start -->
7676

77-
### 方法一
77+
### 方法一:BFS
78+
79+
我们可以使用广度优先搜索(BFS)来解决这个问题。由于数组的长度最多为 6,我们可以通过枚举所有可能的拆分和合并操作来找到最少的操作次数。
80+
81+
我们首先定义一个队列 $\textit{q}$ 来存储当前的数组状态,并使用一个集合 $\textit{vis}$ 来记录已经访问过的数组状态,以避免重复计算。初始时,队列中只包含数组 $\textit{nums1}$。
82+
83+
然后,我们进行以下步骤:
84+
85+
1. 从队列中取出当前的数组状态 $\textit{cur}$。
86+
2. 如果 $\textit{cur}$ 等于目标数组 $\textit{nums2}$,则返回当前的操作次数。
87+
3. 否则,枚举所有可能的拆分位置 $(l, r)$,将子数组 $\textit{cur}[l..r]$ 移除,得到剩余数组 $\textit{remain}$ 和子数组 $\textit{sub}$。
88+
4. 将子数组 $\textit{sub}$ 插入到剩余数组 $\textit{remain}$ 的所有可能位置,生成新的数组状态 $\textit{nxt}$。
89+
5. 如果新的数组状态 $\textit{nxt}$ 没有被访问过,将其加入队列和访问集合中。
90+
6. 重复上述步骤,直到找到目标数组或队列为空。
91+
92+
时间复杂度 $O(n! \times n^4)$,空间复杂度 $O(n! \times n)$,其中 $n$ 是数组的长度。
7893

7994
<!-- tabs:start -->
8095

8196
#### Python3
8297

8398
```python
84-
99+
class Solution:
100+
def minSplitMerge(self, nums1: List[int], nums2: List[int]) -> int:
101+
n = len(nums1)
102+
target = tuple(nums2)
103+
start = tuple(nums1)
104+
105+
q = [start]
106+
vis = set()
107+
vis.add(start)
108+
109+
for ans in count(0):
110+
t = q
111+
q = []
112+
for cur in t:
113+
if cur == target:
114+
return ans
115+
for l in range(n):
116+
for r in range(l, n):
117+
remain = list(cur[:l]) + list(cur[r + 1 :])
118+
sub = cur[l : r + 1]
119+
for i in range(len(remain) + 1):
120+
nxt = tuple(remain[:i] + list(sub) + remain[i:])
121+
if nxt not in vis:
122+
vis.add(nxt)
123+
q.append(nxt)
85124
```
86125

87126
#### Java
88127

89128
```java
90-
129+
class Solution {
130+
public int minSplitMerge(int[] nums1, int[] nums2) {
131+
int n = nums1.length;
132+
List<Integer> target = toList(nums2);
133+
List<Integer> start = toList(nums1);
134+
List<List<Integer>> q = List.of(start);
135+
Set<List<Integer>> vis = new HashSet<>();
136+
vis.add(start);
137+
for (int ans = 0;; ++ans) {
138+
var t = q;
139+
q = new ArrayList<>();
140+
for (var cur : t) {
141+
if (cur.equals(target)) {
142+
return ans;
143+
}
144+
for (int l = 0; l < n; ++l) {
145+
for (int r = l; r < n; ++r) {
146+
List<Integer> remain = new ArrayList<>();
147+
for (int i = 0; i < l; ++i) {
148+
remain.add(cur.get(i));
149+
}
150+
for (int i = r + 1; i < n; ++i) {
151+
remain.add(cur.get(i));
152+
}
153+
List<Integer> sub = cur.subList(l, r + 1);
154+
for (int i = 0; i <= remain.size(); ++i) {
155+
List<Integer> nxt = new ArrayList<>();
156+
for (int j = 0; j < i; ++j) {
157+
nxt.add(remain.get(j));
158+
}
159+
for (int x : sub) {
160+
nxt.add(x);
161+
}
162+
for (int j = i; j < remain.size(); ++j) {
163+
nxt.add(remain.get(j));
164+
}
165+
if (vis.add(nxt)) {
166+
q.add(nxt);
167+
}
168+
}
169+
}
170+
}
171+
}
172+
}
173+
}
174+
175+
private List<Integer> toList(int[] arr) {
176+
List<Integer> res = new ArrayList<>(arr.length);
177+
for (int x : arr) {
178+
res.add(x);
179+
}
180+
return res;
181+
}
182+
}
91183
```
92184

93185
#### C++
94186

95187
```cpp
96-
188+
class Solution {
189+
public:
190+
int minSplitMerge(vector<int>& nums1, vector<int>& nums2) {
191+
int n = nums1.size();
192+
vector<int> target = nums2;
193+
vector<vector<int>> q{nums1};
194+
set<vector<int>> vis;
195+
vis.insert(nums1);
196+
197+
for (int ans = 0;; ++ans) {
198+
vector<vector<int>> t = q;
199+
q.clear();
200+
for (auto& cur : t) {
201+
if (cur == target) {
202+
return ans;
203+
}
204+
for (int l = 0; l < n; ++l) {
205+
for (int r = l; r < n; ++r) {
206+
vector<int> remain;
207+
remain.insert(remain.end(), cur.begin(), cur.begin() + l);
208+
remain.insert(remain.end(), cur.begin() + r + 1, cur.end());
209+
vector<int> sub(cur.begin() + l, cur.begin() + r + 1);
210+
for (int i = 0; i <= (int) remain.size(); ++i) {
211+
vector<int> nxt;
212+
nxt.insert(nxt.end(), remain.begin(), remain.begin() + i);
213+
nxt.insert(nxt.end(), sub.begin(), sub.end());
214+
nxt.insert(nxt.end(), remain.begin() + i, remain.end());
215+
216+
if (!vis.count(nxt)) {
217+
vis.insert(nxt);
218+
q.push_back(nxt);
219+
}
220+
}
221+
}
222+
}
223+
}
224+
}
225+
}
226+
};
97227
```
98228

99229
#### Go
100230

101231
```go
102-
232+
func minSplitMerge(nums1 []int, nums2 []int) int {
233+
n := len(nums1)
234+
235+
toArr := func(nums []int) [6]int {
236+
var t [6]int
237+
for i, x := range nums {
238+
t[i] = x
239+
}
240+
return t
241+
}
242+
243+
start := toArr(nums1)
244+
target := toArr(nums2)
245+
246+
vis := map[[6]int]bool{start: true}
247+
q := [][6]int{start}
248+
249+
for ans := 0; ; ans++ {
250+
nq := [][6]int{}
251+
for _, cur := range q {
252+
if cur == target {
253+
return ans
254+
}
255+
for l := 0; l < n; l++ {
256+
for r := l; r < n; r++ {
257+
remain := []int{}
258+
for i := 0; i < l; i++ {
259+
remain = append(remain, cur[i])
260+
}
261+
for i := r + 1; i < n; i++ {
262+
remain = append(remain, cur[i])
263+
}
264+
265+
sub := []int{}
266+
for i := l; i <= r; i++ {
267+
sub = append(sub, cur[i])
268+
}
269+
270+
for pos := 0; pos <= len(remain); pos++ {
271+
nxtSlice := []int{}
272+
nxtSlice = append(nxtSlice, remain[:pos]...)
273+
nxtSlice = append(nxtSlice, sub...)
274+
nxtSlice = append(nxtSlice, remain[pos:]...)
275+
276+
nxt := toArr(nxtSlice)
277+
if !vis[nxt] {
278+
vis[nxt] = true
279+
nq = append(nq, nxt)
280+
}
281+
}
282+
}
283+
}
284+
}
285+
q = nq
286+
}
287+
}
103288
```
104289

105290
<!-- tabs:end -->

0 commit comments

Comments
 (0)