From 0f802f4fcb9e4758623ffb56644d0f6b324761d0 Mon Sep 17 00:00:00 2001
From: yanglbme <szuyanglb@outlook.com>
Date: Mon, 13 May 2024 17:17:09 +0800
Subject: [PATCH] feat: add solutions to lc problem: No.3149

No.3149.Find the Minimum Cost Array Permutation
---
 .../README.md                                 | 227 +++++++++++++++++-
 .../README_EN.md                              | 227 +++++++++++++++++-
 .../Solution.cpp                              |  42 ++++
 .../Solution.go                               |  52 ++++
 .../Solution.java                             |  47 ++++
 .../Solution.py                               |  27 +++
 .../Solution.ts                               |  37 +++
 7 files changed, 651 insertions(+), 8 deletions(-)
 create mode 100644 solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.cpp
 create mode 100644 solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.go
 create mode 100644 solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.java
 create mode 100644 solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.py
 create mode 100644 solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.ts

diff --git a/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/README.md b/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/README.md
index 004a6b897aa93..dc34a153748f6 100644
--- a/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/README.md	
+++ b/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/README.md	
@@ -55,24 +55,243 @@
 
 ## 解法
 
-### 方法一
+### 方法一:记忆化搜索
+
+我们注意到,对于任意一个排列 $\text{perm}$,把它循环向左移动任意次,得到的排列分数依然是相同的。由于题目要求返回字典序最小的排列,因此我们可以确定排列的第一个元素一定是 $0$。
+
+另外,由于题目的数据范围不超过 $14$,我们可以考虑使用状态压缩的方法,来表示当前排列选取的数字集合。我们用一个长度为 $n$ 的二进制数 $\text{mask}$ 来表示当前排列选取的数字集合,其中 $\text{mask}$ 的第 $i$ 位为 $1$ 表示数字 $i$ 已经被选取,为 $0$ 表示数字 $i$ 还未被选取。
+
+我们设计一个函数 $\text{dfs}(\text{mask}, \text{pre})$,表示当前排列选取的数字集合为 $\text{mask}$,且最后一个选取的数字为 $\text{pre}$ 时,得到的排列的最小分数。初始时我们将数字 $0$ 加入到排列中。
+
+函数 $\text{dfs}(\text{mask}, \text{pre})$ 的计算过程如下:
+
+-   如果 $\text{mask}$ 的二进制表示中 $1$ 的个数为 $n$,即 $\text{mask} = 2^n - 1$,表示所有数字都已经被选取,此时返回 $\text{abs}(\text{pre} - \text{nums}[0])$;
+-   否则,我们枚举下一个选取的数字 $\text{cur}$,如果数字 $\text{cur}$ 还未被选取,那么我们可以将数字 $\text{cur}$ 加入到排列中,此时排列的分数为 $|\text{pre} - \text{nums}[\text{cur}]| + \text{dfs}(\text{mask} \, | \, 1 << \text{cur}, \text{cur})$,我们需要取所有 $\text{cur}$ 中分数的最小值。
+
+最后,我们利用一个函数 $\text{g}(\text{mask}, \text{pre})$ 来构造得到最小分数的排列。我们首先将数字 $\text{pre}$ 加入到排列中,然后枚举下一个选取的数字 $\text{cur}$,如果数字 $\text{cur}$ 还未被选取,且满足 $|\text{pre} - \text{nums}[\text{cur}]| + \text{dfs}(\text{mask} \, | \, 1 << \text{cur}, \text{cur})$ 的值等于 $\text{dfs}(\text{mask}, \text{pre})$,那么我们就可以将数字 $\text{cur}$ 加入到排列中。
+
+时间复杂度 $(n^2 \times 2^n)$,空间复杂度 $O(n \times 2^n)$。其中 $n$ 为数组 $\text{nums}$ 的长度。
 
 <!-- tabs:start -->
 
 ```python
-
+class Solution:
+    def findPermutation(self, nums: List[int]) -> List[int]:
+        @cache
+        def dfs(mask: int, pre: int) -> int:
+            if mask == (1 << n) - 1:
+                return abs(pre - nums[0])
+            res = inf
+            for cur in range(1, n):
+                if mask >> cur & 1 ^ 1:
+                    res = min(res, abs(pre - nums[cur]) + dfs(mask | 1 << cur, cur))
+            return res
+
+        def g(mask: int, pre: int):
+            ans.append(pre)
+            if mask == (1 << n) - 1:
+                return
+            res = dfs(mask, pre)
+            for cur in range(1, n):
+                if mask >> cur & 1 ^ 1:
+                    if abs(pre - nums[cur]) + dfs(mask | 1 << cur, cur) == res:
+                        g(mask | 1 << cur, cur)
+                        break
+
+        n = len(nums)
+        ans = []
+        g(1, 0)
+        return ans
 ```
 
 ```java
-
+class Solution {
+    private Integer[][] f;
+    private int[] nums;
+    private int[] ans;
+    private int n;
+
+    public int[] findPermutation(int[] nums) {
+        n = nums.length;
+        ans = new int[n];
+        this.nums = nums;
+        f = new Integer[1 << n][n];
+        g(1, 0, 0);
+        return ans;
+    }
+
+    private int dfs(int mask, int pre) {
+        if (mask == (1 << n) - 1) {
+            return Math.abs(pre - nums[0]);
+        }
+        if (f[mask][pre] != null) {
+            return f[mask][pre];
+        }
+        int res = Integer.MAX_VALUE;
+        for (int cur = 1; cur < n; ++cur) {
+            if ((mask >> cur & 1) == 0) {
+                res = Math.min(res, Math.abs(pre - nums[cur]) + dfs(mask | 1 << cur, cur));
+            }
+        }
+        return f[mask][pre] = res;
+    }
+
+    private void g(int mask, int pre, int k) {
+        ans[k] = pre;
+        if (mask == (1 << n) - 1) {
+            return;
+        }
+        int res = dfs(mask, pre);
+        for (int cur = 1; cur < n; ++cur) {
+            if ((mask >> cur & 1) == 0) {
+                if (Math.abs(pre - nums[cur]) + dfs(mask | 1 << cur, cur) == res) {
+                    g(mask | 1 << cur, cur, k + 1);
+                    break;
+                }
+            }
+        }
+    }
+}
 ```
 
 ```cpp
-
+class Solution {
+public:
+    vector<int> findPermutation(vector<int>& nums) {
+        int n = nums.size();
+        vector<int> ans;
+        int f[1 << n][n];
+        memset(f, -1, sizeof(f));
+        function<int(int, int)> dfs = [&](int mask, int pre) {
+            if (mask == (1 << n) - 1) {
+                return abs(pre - nums[0]);
+            }
+            int* res = &f[mask][pre];
+            if (*res != -1) {
+                return *res;
+            }
+            *res = INT_MAX;
+            for (int cur = 1; cur < n; ++cur) {
+                if (mask >> cur & 1 ^ 1) {
+                    *res = min(*res, abs(pre - nums[cur]) + dfs(mask | 1 << cur, cur));
+                }
+            }
+            return *res;
+        };
+        function<void(int, int)> g = [&](int mask, int pre) {
+            ans.push_back(pre);
+            if (mask == (1 << n) - 1) {
+                return;
+            }
+            int res = dfs(mask, pre);
+            for (int cur = 1; cur < n; ++cur) {
+                if (mask >> cur & 1 ^ 1) {
+                    if (abs(pre - nums[cur]) + dfs(mask | 1 << cur, cur) == res) {
+                        g(mask | 1 << cur, cur);
+                        break;
+                    }
+                }
+            }
+        };
+        g(1, 0);
+        return ans;
+    }
+};
 ```
 
 ```go
+func findPermutation(nums []int) (ans []int) {
+	n := len(nums)
+	f := make([][]int, 1<<n)
+	for i := range f {
+		f[i] = make([]int, n)
+		for j := range f[i] {
+			f[i][j] = -1
+		}
+	}
+	var dfs func(int, int) int
+	dfs = func(mask, pre int) int {
+		if mask == 1<<n-1 {
+			return abs(pre - nums[0])
+		}
+		if f[mask][pre] != -1 {
+			return f[mask][pre]
+		}
+		res := &f[mask][pre]
+		*res = math.MaxInt32
+		for cur := 1; cur < n; cur++ {
+			if mask>>cur&1 == 0 {
+				*res = min(*res, abs(pre-nums[cur])+dfs(mask|1<<cur, cur))
+			}
+		}
+		return *res
+	}
+	var g func(int, int)
+	g = func(mask, pre int) {
+		ans = append(ans, pre)
+		if mask == 1<<n-1 {
+			return
+		}
+		res := dfs(mask, pre)
+		for cur := 1; cur < n; cur++ {
+			if mask>>cur&1 == 0 {
+				if abs(pre-nums[cur])+dfs(mask|1<<cur, cur) == res {
+					g(mask|1<<cur, cur)
+					break
+				}
+			}
+		}
+	}
+	g(1, 0)
+	return
+}
+
+func abs(x int) int {
+	if x < 0 {
+		return -x
+	}
+	return x
+}
+```
 
+```ts
+function findPermutation(nums: number[]): number[] {
+    const n = nums.length;
+    const ans: number[] = [];
+    const f: number[][] = Array.from({ length: 1 << n }, () => Array(n).fill(-1));
+    const dfs = (mask: number, pre: number): number => {
+        if (mask === (1 << n) - 1) {
+            return Math.abs(pre - nums[0]);
+        }
+        if (f[mask][pre] !== -1) {
+            return f[mask][pre];
+        }
+        let res = Infinity;
+        for (let cur = 1; cur < n; ++cur) {
+            if (((mask >> cur) & 1) ^ 1) {
+                res = Math.min(res, Math.abs(pre - nums[cur]) + dfs(mask | (1 << cur), cur));
+            }
+        }
+        return (f[mask][pre] = res);
+    };
+    const g = (mask: number, pre: number) => {
+        ans.push(pre);
+        if (mask === (1 << n) - 1) {
+            return;
+        }
+        const res = dfs(mask, pre);
+        for (let cur = 1; cur < n; ++cur) {
+            if (((mask >> cur) & 1) ^ 1) {
+                if (Math.abs(pre - nums[cur]) + dfs(mask | (1 << cur), cur) === res) {
+                    g(mask | (1 << cur), cur);
+                    break;
+                }
+            }
+        }
+    };
+    g(1, 0);
+    return ans;
+}
 ```
 
 <!-- tabs:end -->
diff --git a/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/README_EN.md b/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/README_EN.md
index a3d637bba9e98..837790f976f3a 100644
--- a/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/README_EN.md	
+++ b/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/README_EN.md	
@@ -51,24 +51,243 @@
 
 ## Solutions
 
-### Solution 1
+### Solution 1: Memoization Search
+
+We notice that for any permutation $\text{perm}$, if we cyclically shift it to the left any number of times, the score of the permutation remains the same. Since the problem requires returning the lexicographically smallest permutation, we can determine that the first element of the permutation must be $0$.
+
+Also, since the data range of the problem does not exceed $14$, we can consider using the method of state compression to represent the set of numbers selected in the current permutation. We use a binary number $\text{mask}$ of length $n$ to represent the set of numbers selected in the current permutation, where the $i$-th bit of $\text{mask}$ is $1$ indicates that the number $i$ has been selected, and $0$ indicates that the number $i$ has not been selected yet.
+
+We design a function $\text{dfs}(\text{mask}, \text{pre})$, which represents the minimum score of the permutation obtained when the set of numbers selected in the current permutation is $\text{mask}$ and the last selected number is $\text{pre}$. Initially, we add the number $0$ to the permutation.
+
+The calculation process of the function $\text{dfs}(\text{mask}, \text{pre})$ is as follows:
+
+-   If the number of $1$s in the binary representation of $\text{mask}$ is $n$, that is, $\text{mask} = 2^n - 1$, it means that all numbers have been selected, then return $\text{abs}(\text{pre} - \text{nums}[0])$;
+-   Otherwise, we enumerate the next selected number $\text{cur}$. If the number $\text{cur}$ has not been selected yet, then we can add the number $\text{cur}$ to the permutation. At this time, the score of the permutation is $|\text{pre} - \text{nums}[\text{cur}]| + \text{dfs}(\text{mask} \, | \, 1 << \text{cur}, \text{cur})$. We need to take the minimum score among all $\text{cur}$.
+
+Finally, we use a function $\text{g}(\text{mask}, \text{pre})$ to construct the permutation that gets the minimum score. We first add the number $\text{pre}$ to the permutation, and then enumerate the next selected number $\text{cur}$. If the number $\text{cur}$ has not been selected yet, and it satisfies that the value of $|\text{pre} - \text{nums}[\text{cur}]| + \text{dfs}(\text{mask} \, | \, 1 << \text{cur}, \text{cur})$ is equal to $\text{dfs}(\text{mask}, \text{pre})$, then we can add the number $\text{cur}$ to the permutation.
+
+The time complexity is $(n^2 \times 2^n)$, and the space complexity is $O(n \times 2^n)$. Where $n$ is the length of the array $\text{nums}$.
 
 <!-- tabs:start -->
 
 ```python
-
+class Solution:
+    def findPermutation(self, nums: List[int]) -> List[int]:
+        @cache
+        def dfs(mask: int, pre: int) -> int:
+            if mask == (1 << n) - 1:
+                return abs(pre - nums[0])
+            res = inf
+            for cur in range(1, n):
+                if mask >> cur & 1 ^ 1:
+                    res = min(res, abs(pre - nums[cur]) + dfs(mask | 1 << cur, cur))
+            return res
+
+        def g(mask: int, pre: int):
+            ans.append(pre)
+            if mask == (1 << n) - 1:
+                return
+            res = dfs(mask, pre)
+            for cur in range(1, n):
+                if mask >> cur & 1 ^ 1:
+                    if abs(pre - nums[cur]) + dfs(mask | 1 << cur, cur) == res:
+                        g(mask | 1 << cur, cur)
+                        break
+
+        n = len(nums)
+        ans = []
+        g(1, 0)
+        return ans
 ```
 
 ```java
-
+class Solution {
+    private Integer[][] f;
+    private int[] nums;
+    private int[] ans;
+    private int n;
+
+    public int[] findPermutation(int[] nums) {
+        n = nums.length;
+        ans = new int[n];
+        this.nums = nums;
+        f = new Integer[1 << n][n];
+        g(1, 0, 0);
+        return ans;
+    }
+
+    private int dfs(int mask, int pre) {
+        if (mask == (1 << n) - 1) {
+            return Math.abs(pre - nums[0]);
+        }
+        if (f[mask][pre] != null) {
+            return f[mask][pre];
+        }
+        int res = Integer.MAX_VALUE;
+        for (int cur = 1; cur < n; ++cur) {
+            if ((mask >> cur & 1) == 0) {
+                res = Math.min(res, Math.abs(pre - nums[cur]) + dfs(mask | 1 << cur, cur));
+            }
+        }
+        return f[mask][pre] = res;
+    }
+
+    private void g(int mask, int pre, int k) {
+        ans[k] = pre;
+        if (mask == (1 << n) - 1) {
+            return;
+        }
+        int res = dfs(mask, pre);
+        for (int cur = 1; cur < n; ++cur) {
+            if ((mask >> cur & 1) == 0) {
+                if (Math.abs(pre - nums[cur]) + dfs(mask | 1 << cur, cur) == res) {
+                    g(mask | 1 << cur, cur, k + 1);
+                    break;
+                }
+            }
+        }
+    }
+}
 ```
 
 ```cpp
-
+class Solution {
+public:
+    vector<int> findPermutation(vector<int>& nums) {
+        int n = nums.size();
+        vector<int> ans;
+        int f[1 << n][n];
+        memset(f, -1, sizeof(f));
+        function<int(int, int)> dfs = [&](int mask, int pre) {
+            if (mask == (1 << n) - 1) {
+                return abs(pre - nums[0]);
+            }
+            int* res = &f[mask][pre];
+            if (*res != -1) {
+                return *res;
+            }
+            *res = INT_MAX;
+            for (int cur = 1; cur < n; ++cur) {
+                if (mask >> cur & 1 ^ 1) {
+                    *res = min(*res, abs(pre - nums[cur]) + dfs(mask | 1 << cur, cur));
+                }
+            }
+            return *res;
+        };
+        function<void(int, int)> g = [&](int mask, int pre) {
+            ans.push_back(pre);
+            if (mask == (1 << n) - 1) {
+                return;
+            }
+            int res = dfs(mask, pre);
+            for (int cur = 1; cur < n; ++cur) {
+                if (mask >> cur & 1 ^ 1) {
+                    if (abs(pre - nums[cur]) + dfs(mask | 1 << cur, cur) == res) {
+                        g(mask | 1 << cur, cur);
+                        break;
+                    }
+                }
+            }
+        };
+        g(1, 0);
+        return ans;
+    }
+};
 ```
 
 ```go
+func findPermutation(nums []int) (ans []int) {
+	n := len(nums)
+	f := make([][]int, 1<<n)
+	for i := range f {
+		f[i] = make([]int, n)
+		for j := range f[i] {
+			f[i][j] = -1
+		}
+	}
+	var dfs func(int, int) int
+	dfs = func(mask, pre int) int {
+		if mask == 1<<n-1 {
+			return abs(pre - nums[0])
+		}
+		if f[mask][pre] != -1 {
+			return f[mask][pre]
+		}
+		res := &f[mask][pre]
+		*res = math.MaxInt32
+		for cur := 1; cur < n; cur++ {
+			if mask>>cur&1 == 0 {
+				*res = min(*res, abs(pre-nums[cur])+dfs(mask|1<<cur, cur))
+			}
+		}
+		return *res
+	}
+	var g func(int, int)
+	g = func(mask, pre int) {
+		ans = append(ans, pre)
+		if mask == 1<<n-1 {
+			return
+		}
+		res := dfs(mask, pre)
+		for cur := 1; cur < n; cur++ {
+			if mask>>cur&1 == 0 {
+				if abs(pre-nums[cur])+dfs(mask|1<<cur, cur) == res {
+					g(mask|1<<cur, cur)
+					break
+				}
+			}
+		}
+	}
+	g(1, 0)
+	return
+}
+
+func abs(x int) int {
+	if x < 0 {
+		return -x
+	}
+	return x
+}
+```
 
+```ts
+function findPermutation(nums: number[]): number[] {
+    const n = nums.length;
+    const ans: number[] = [];
+    const f: number[][] = Array.from({ length: 1 << n }, () => Array(n).fill(-1));
+    const dfs = (mask: number, pre: number): number => {
+        if (mask === (1 << n) - 1) {
+            return Math.abs(pre - nums[0]);
+        }
+        if (f[mask][pre] !== -1) {
+            return f[mask][pre];
+        }
+        let res = Infinity;
+        for (let cur = 1; cur < n; ++cur) {
+            if (((mask >> cur) & 1) ^ 1) {
+                res = Math.min(res, Math.abs(pre - nums[cur]) + dfs(mask | (1 << cur), cur));
+            }
+        }
+        return (f[mask][pre] = res);
+    };
+    const g = (mask: number, pre: number) => {
+        ans.push(pre);
+        if (mask === (1 << n) - 1) {
+            return;
+        }
+        const res = dfs(mask, pre);
+        for (let cur = 1; cur < n; ++cur) {
+            if (((mask >> cur) & 1) ^ 1) {
+                if (Math.abs(pre - nums[cur]) + dfs(mask | (1 << cur), cur) === res) {
+                    g(mask | (1 << cur), cur);
+                    break;
+                }
+            }
+        }
+    };
+    g(1, 0);
+    return ans;
+}
 ```
 
 <!-- tabs:end -->
diff --git a/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.cpp b/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.cpp
new file mode 100644
index 0000000000000..79ff63d773209
--- /dev/null
+++ b/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.cpp	
@@ -0,0 +1,42 @@
+class Solution {
+public:
+    vector<int> findPermutation(vector<int>& nums) {
+        int n = nums.size();
+        vector<int> ans;
+        int f[1 << n][n];
+        memset(f, -1, sizeof(f));
+        function<int(int, int)> dfs = [&](int mask, int pre) {
+            if (mask == (1 << n) - 1) {
+                return abs(pre - nums[0]);
+            }
+            int* res = &f[mask][pre];
+            if (*res != -1) {
+                return *res;
+            }
+            *res = INT_MAX;
+            for (int cur = 1; cur < n; ++cur) {
+                if (mask >> cur & 1 ^ 1) {
+                    *res = min(*res, abs(pre - nums[cur]) + dfs(mask | 1 << cur, cur));
+                }
+            }
+            return *res;
+        };
+        function<void(int, int)> g = [&](int mask, int pre) {
+            ans.push_back(pre);
+            if (mask == (1 << n) - 1) {
+                return;
+            }
+            int res = dfs(mask, pre);
+            for (int cur = 1; cur < n; ++cur) {
+                if (mask >> cur & 1 ^ 1) {
+                    if (abs(pre - nums[cur]) + dfs(mask | 1 << cur, cur) == res) {
+                        g(mask | 1 << cur, cur);
+                        break;
+                    }
+                }
+            }
+        };
+        g(1, 0);
+        return ans;
+    }
+};
\ No newline at end of file
diff --git a/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.go b/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.go
new file mode 100644
index 0000000000000..abc2986f1b6cb
--- /dev/null
+++ b/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.go	
@@ -0,0 +1,52 @@
+func findPermutation(nums []int) (ans []int) {
+	n := len(nums)
+	f := make([][]int, 1<<n)
+	for i := range f {
+		f[i] = make([]int, n)
+		for j := range f[i] {
+			f[i][j] = -1
+		}
+	}
+	var dfs func(int, int) int
+	dfs = func(mask, pre int) int {
+		if mask == 1<<n-1 {
+			return abs(pre - nums[0])
+		}
+		if f[mask][pre] != -1 {
+			return f[mask][pre]
+		}
+		res := &f[mask][pre]
+		*res = math.MaxInt32
+		for cur := 1; cur < n; cur++ {
+			if mask>>cur&1 == 0 {
+				*res = min(*res, abs(pre-nums[cur])+dfs(mask|1<<cur, cur))
+			}
+		}
+		return *res
+	}
+	var g func(int, int)
+	g = func(mask, pre int) {
+		ans = append(ans, pre)
+		if mask == 1<<n-1 {
+			return
+		}
+		res := dfs(mask, pre)
+		for cur := 1; cur < n; cur++ {
+			if mask>>cur&1 == 0 {
+				if abs(pre-nums[cur])+dfs(mask|1<<cur, cur) == res {
+					g(mask|1<<cur, cur)
+					break
+				}
+			}
+		}
+	}
+	g(1, 0)
+	return
+}
+
+func abs(x int) int {
+	if x < 0 {
+		return -x
+	}
+	return x
+}
\ No newline at end of file
diff --git a/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.java b/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.java
new file mode 100644
index 0000000000000..d30a86bcbbd58
--- /dev/null
+++ b/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.java	
@@ -0,0 +1,47 @@
+class Solution {
+    private Integer[][] f;
+    private int[] nums;
+    private int[] ans;
+    private int n;
+
+    public int[] findPermutation(int[] nums) {
+        n = nums.length;
+        ans = new int[n];
+        this.nums = nums;
+        f = new Integer[1 << n][n];
+        g(1, 0, 0);
+        return ans;
+    }
+
+    private int dfs(int mask, int pre) {
+        if (mask == (1 << n) - 1) {
+            return Math.abs(pre - nums[0]);
+        }
+        if (f[mask][pre] != null) {
+            return f[mask][pre];
+        }
+        int res = Integer.MAX_VALUE;
+        for (int cur = 1; cur < n; ++cur) {
+            if ((mask >> cur & 1) == 0) {
+                res = Math.min(res, Math.abs(pre - nums[cur]) + dfs(mask | 1 << cur, cur));
+            }
+        }
+        return f[mask][pre] = res;
+    }
+
+    private void g(int mask, int pre, int k) {
+        ans[k] = pre;
+        if (mask == (1 << n) - 1) {
+            return;
+        }
+        int res = dfs(mask, pre);
+        for (int cur = 1; cur < n; ++cur) {
+            if ((mask >> cur & 1) == 0) {
+                if (Math.abs(pre - nums[cur]) + dfs(mask | 1 << cur, cur) == res) {
+                    g(mask | 1 << cur, cur, k + 1);
+                    break;
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.py b/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.py
new file mode 100644
index 0000000000000..c2b3bb7b12bc4
--- /dev/null
+++ b/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.py	
@@ -0,0 +1,27 @@
+class Solution:
+    def findPermutation(self, nums: List[int]) -> List[int]:
+        @cache
+        def dfs(mask: int, pre: int) -> int:
+            if mask == (1 << n) - 1:
+                return abs(pre - nums[0])
+            res = inf
+            for cur in range(1, n):
+                if mask >> cur & 1 ^ 1:
+                    res = min(res, abs(pre - nums[cur]) + dfs(mask | 1 << cur, cur))
+            return res
+
+        def g(mask: int, pre: int):
+            ans.append(pre)
+            if mask == (1 << n) - 1:
+                return
+            res = dfs(mask, pre)
+            for cur in range(1, n):
+                if mask >> cur & 1 ^ 1:
+                    if abs(pre - nums[cur]) + dfs(mask | 1 << cur, cur) == res:
+                        g(mask | 1 << cur, cur)
+                        break
+
+        n = len(nums)
+        ans = []
+        g(1, 0)
+        return ans
diff --git a/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.ts b/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.ts
new file mode 100644
index 0000000000000..9770825220bc0
--- /dev/null
+++ b/solution/3100-3199/3149.Find the Minimum Cost Array Permutation/Solution.ts	
@@ -0,0 +1,37 @@
+function findPermutation(nums: number[]): number[] {
+    const n = nums.length;
+    const ans: number[] = [];
+    const f: number[][] = Array.from({ length: 1 << n }, () => Array(n).fill(-1));
+    const dfs = (mask: number, pre: number): number => {
+        if (mask === (1 << n) - 1) {
+            return Math.abs(pre - nums[0]);
+        }
+        if (f[mask][pre] !== -1) {
+            return f[mask][pre];
+        }
+        let res = Infinity;
+        for (let cur = 1; cur < n; ++cur) {
+            if (((mask >> cur) & 1) ^ 1) {
+                res = Math.min(res, Math.abs(pre - nums[cur]) + dfs(mask | (1 << cur), cur));
+            }
+        }
+        return (f[mask][pre] = res);
+    };
+    const g = (mask: number, pre: number) => {
+        ans.push(pre);
+        if (mask === (1 << n) - 1) {
+            return;
+        }
+        const res = dfs(mask, pre);
+        for (let cur = 1; cur < n; ++cur) {
+            if (((mask >> cur) & 1) ^ 1) {
+                if (Math.abs(pre - nums[cur]) + dfs(mask | (1 << cur), cur) === res) {
+                    g(mask | (1 << cur), cur);
+                    break;
+                }
+            }
+        }
+    };
+    g(1, 0);
+    return ans;
+}