Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 190 additions & 5 deletions solution/3600-3699/3690.Split and Merge Array Transformation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,32 +74,217 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3690.Sp

<!-- solution:start -->

### 方法一
### 方法一:BFS

我们可以使用广度优先搜索(BFS)来解决这个问题。由于数组的长度最多为 6,我们可以通过枚举所有可能的拆分和合并操作来找到最少的操作次数。

我们首先定义一个队列 $\textit{q}$ 来存储当前的数组状态,并使用一个集合 $\textit{vis}$ 来记录已经访问过的数组状态,以避免重复计算。初始时,队列中只包含数组 $\textit{nums1}$。

然后,我们进行以下步骤:

1. 从队列中取出当前的数组状态 $\textit{cur}$。
2. 如果 $\textit{cur}$ 等于目标数组 $\textit{nums2}$,则返回当前的操作次数。
3. 否则,枚举所有可能的拆分位置 $(l, r)$,将子数组 $\textit{cur}[l..r]$ 移除,得到剩余数组 $\textit{remain}$ 和子数组 $\textit{sub}$。
4. 将子数组 $\textit{sub}$ 插入到剩余数组 $\textit{remain}$ 的所有可能位置,生成新的数组状态 $\textit{nxt}$。
5. 如果新的数组状态 $\textit{nxt}$ 没有被访问过,将其加入队列和访问集合中。
6. 重复上述步骤,直到找到目标数组或队列为空。

时间复杂度 $O(n! \times n^4)$,空间复杂度 $O(n! \times n)$,其中 $n$ 是数组的长度。

<!-- tabs:start -->

#### Python3

```python

class Solution:
def minSplitMerge(self, nums1: List[int], nums2: List[int]) -> int:
n = len(nums1)
target = tuple(nums2)
start = tuple(nums1)

q = [start]
vis = set()
vis.add(start)

for ans in count(0):
t = q
q = []
for cur in t:
if cur == target:
return ans
for l in range(n):
for r in range(l, n):
remain = list(cur[:l]) + list(cur[r + 1 :])
sub = cur[l : r + 1]
for i in range(len(remain) + 1):
nxt = tuple(remain[:i] + list(sub) + remain[i:])
if nxt not in vis:
vis.add(nxt)
q.append(nxt)
```

#### Java

```java

class Solution {
public int minSplitMerge(int[] nums1, int[] nums2) {
int n = nums1.length;
List<Integer> target = toList(nums2);
List<Integer> start = toList(nums1);
List<List<Integer>> q = List.of(start);
Set<List<Integer>> vis = new HashSet<>();
vis.add(start);
for (int ans = 0;; ++ans) {
var t = q;
q = new ArrayList<>();
for (var cur : t) {
if (cur.equals(target)) {
return ans;
}
for (int l = 0; l < n; ++l) {
for (int r = l; r < n; ++r) {
List<Integer> remain = new ArrayList<>();
for (int i = 0; i < l; ++i) {
remain.add(cur.get(i));
}
for (int i = r + 1; i < n; ++i) {
remain.add(cur.get(i));
}
List<Integer> sub = cur.subList(l, r + 1);
for (int i = 0; i <= remain.size(); ++i) {
List<Integer> nxt = new ArrayList<>();
for (int j = 0; j < i; ++j) {
nxt.add(remain.get(j));
}
for (int x : sub) {
nxt.add(x);
}
for (int j = i; j < remain.size(); ++j) {
nxt.add(remain.get(j));
}
if (vis.add(nxt)) {
q.add(nxt);
}
}
}
}
}
}
}

private List<Integer> toList(int[] arr) {
List<Integer> res = new ArrayList<>(arr.length);
for (int x : arr) {
res.add(x);
}
return res;
}
}
```

#### C++

```cpp

class Solution {
public:
int minSplitMerge(vector<int>& nums1, vector<int>& nums2) {
int n = nums1.size();
vector<int> target = nums2;
vector<vector<int>> q{nums1};
set<vector<int>> vis;
vis.insert(nums1);

for (int ans = 0;; ++ans) {
vector<vector<int>> t = q;
q.clear();
for (auto& cur : t) {
if (cur == target) {
return ans;
}
for (int l = 0; l < n; ++l) {
for (int r = l; r < n; ++r) {
vector<int> remain;
remain.insert(remain.end(), cur.begin(), cur.begin() + l);
remain.insert(remain.end(), cur.begin() + r + 1, cur.end());
vector<int> sub(cur.begin() + l, cur.begin() + r + 1);
for (int i = 0; i <= (int) remain.size(); ++i) {
vector<int> nxt;
nxt.insert(nxt.end(), remain.begin(), remain.begin() + i);
nxt.insert(nxt.end(), sub.begin(), sub.end());
nxt.insert(nxt.end(), remain.begin() + i, remain.end());

if (!vis.count(nxt)) {
vis.insert(nxt);
q.push_back(nxt);
}
}
}
}
}
}
}
};
```

#### Go

```go

func minSplitMerge(nums1 []int, nums2 []int) int {
n := len(nums1)

toArr := func(nums []int) [6]int {
var t [6]int
for i, x := range nums {
t[i] = x
}
return t
}

start := toArr(nums1)
target := toArr(nums2)

vis := map[[6]int]bool{start: true}
q := [][6]int{start}

for ans := 0; ; ans++ {
nq := [][6]int{}
for _, cur := range q {
if cur == target {
return ans
}
for l := 0; l < n; l++ {
for r := l; r < n; r++ {
remain := []int{}
for i := 0; i < l; i++ {
remain = append(remain, cur[i])
}
for i := r + 1; i < n; i++ {
remain = append(remain, cur[i])
}

sub := []int{}
for i := l; i <= r; i++ {
sub = append(sub, cur[i])
}

for pos := 0; pos <= len(remain); pos++ {
nxtSlice := []int{}
nxtSlice = append(nxtSlice, remain[:pos]...)
nxtSlice = append(nxtSlice, sub...)
nxtSlice = append(nxtSlice, remain[pos:]...)

nxt := toArr(nxtSlice)
if !vis[nxt] {
vis[nxt] = true
nq = append(nq, nxt)
}
}
}
}
}
q = nq
}
}
```

<!-- tabs:end -->
Expand Down
Loading