@@ -74,32 +74,217 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3690.Sp
74
74
75
75
<!-- solution:start -->
76
76
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$ 是数组的长度。
78
93
79
94
<!-- tabs:start -->
80
95
81
96
#### Python3
82
97
83
98
``` 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)
85
124
```
86
125
87
126
#### Java
88
127
89
128
``` 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
+ }
91
183
```
92
184
93
185
#### C++
94
186
95
187
``` 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
+ };
97
227
```
98
228
99
229
#### Go
100
230
101
231
``` 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
+ }
103
288
```
104
289
105
290
<!-- tabs:end -->
0 commit comments