comments | difficulty | edit_url | rating | source | tags | ||||
---|---|---|---|---|---|---|---|---|---|
true |
Hard |
2641 |
Weekly Contest 397 Q4 |
|
You are given an array nums
which is a permutation of [0, 1, 2, ..., n - 1]
. The score of any permutation of [0, 1, 2, ..., n - 1]
named perm
is defined as:
score(perm) = |perm[0] - nums[perm[1]]| + |perm[1] - nums[perm[2]]| + ... + |perm[n - 1] - nums[perm[0]]|
Return the permutation perm
which has the minimum possible score. If multiple permutations exist with this score, return the one that is lexicographically smallest among them.
Example 1:
Input: nums = [1,0,2]
Output: [0,1,2]
Explanation:
The lexicographically smallest permutation with minimum cost is [0,1,2]
. The cost of this permutation is |0 - 0| + |1 - 2| + |2 - 1| = 2
.
Example 2:
Input: nums = [0,2,1]
Output: [0,2,1]
Explanation:
The lexicographically smallest permutation with minimum cost is [0,2,1]
. The cost of this permutation is |0 - 1| + |2 - 2| + |1 - 0| = 2
.
Constraints:
2 <= n == nums.length <= 14
nums
is a permutation of[0, 1, 2, ..., n - 1]
.
We notice that for any permutation
Also, since the data range of the problem does not exceed
We design a function
The calculation process of the function
- If the number of $1$s in the binary representation of
$\textit{mask}$ is$n$ , that is,$\textit{mask} = 2^n - 1$ , it means that all numbers have been selected, then return$|\textit{pre} - \textit{nums}[0]|$ ; - Otherwise, we enumerate the next selected number
$\textit{cur}$ . If the number$\textit{cur}$ has not been selected yet, then we can add the number$\textit{cur}$ to the permutation. At this time, the score of the permutation is$|\textit{pre} - \textit{nums}[\textit{cur}]| + \textit{dfs}(\textit{mask} , | , 1 << \textit{cur}, \textit{cur})$ . We need to take the minimum score among all$\textit{cur}$ .
Finally, we use a function
The time complexity is
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
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;
}
}
}
}
}
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;
}
};
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
}
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;
}