@@ -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