Article directory
47. Full Arrangement II:
Given a sequence that may contain repeating numbers nums
, return all non-repeating full permutations in any order .
Example 1:
输入:
nums = [1,1,2]
输出:
[[1,1,2],
[1,2,1],
[2,1,1]]
Example 2:
输入:
nums = [1,2,3]
输出:
[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
hint:
- 1 <= nums.length <= 8
- -10 <= nums[i] <= 10
analyze:
- Facing this algorithm problem, the second master fell into deep thought.
- To do a full arrangement, backtracking is the general direction.
- If there are repeated numbers and non-repeated arrangements, deduplication is a must.
- The requirement is to deduplicate the permutation, but it can also be understood as skipping numbers that have been "tried" when backtracking.
- If there are many numbers, you can consider the counting sorting method, where the order is not important, the important thing is to quickly remove the duplication.
- But the prompt says that there are up to 8 numbers, so sort them directly. The same order is not important, just for the same numbers to be next to each other, and skip the same numbers every time you go back.
answer:
rust
impl Solution {
pub fn permute_unique(mut nums: Vec<i32>) -> Vec<Vec<i32>> {
fn backtrack(nums: &Vec<i32>, ans: &mut Vec<Vec<i32>>, vis: &mut Vec<bool>, row: &mut Vec<i32>) {
if row.len() == nums.len() {
ans.push(row.clone());
return;
}
nums.iter().enumerate().for_each(|(i, v)| {
if !vis[i] && (i == 0 || nums[i] != nums[i - 1] || vis[i - 1]) {
row.push(nums[i]);
vis[i] = true;
backtrack(nums, ans, vis, row);
row.pop();
vis[i] = false;
}
});
}
let mut ans = Vec::new();
nums.sort();
let mut vis = vec![false; nums.len()];
let mut row = Vec::new();
backtrack(&mut nums, &mut ans, &mut vis, &mut row);
return ans;
}
}
go
func permuteUnique(nums []int) (ans [][]int) {
var backtrack func([]bool, []int)
backtrack = func(vis []bool, row []int) {
if len(row) == len(nums) {
ans = append(ans, append([]int(nil), row...))
return
}
for i, v := range nums {
if vis[i] || i > 0 && !vis[i-1] && v == nums[i-1] {
continue
}
row = append(row, v)
vis[i] = true
backtrack(vis, row)
row = row[:len(row)-1]
vis[i] = false
}
}
sort.Ints(nums)
backtrack(make([]bool, len(nums)), []int{
})
return
}
c++
class Solution {
private:
void backtrack(vector<int>& nums, vector<vector<int>>& ans, vector<bool>& vis, vector<int>& row) {
if (row.size() == nums.size()) {
ans.emplace_back(row);
return;
}
for (int i = 0; i < nums.size(); ++i) {
if (vis[i] || (i > 0 && nums[i] == nums[i - 1] && !vis[i - 1])) {
continue;
}
row.emplace_back(nums[i]);
vis[i] = true;
backtrack(nums, ans, vis, row);
row.pop_back();
vis[i] = false;
}
}
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<vector<int>> ans;
vector<int> row;
vector<bool> vis(nums.size(), false);
sort(nums.begin(), nums.end());
backtrack(nums, ans, vis, row);
return ans;
}
};
c
int cmp(void* a, void* b) {
return *(int*)a - *(int*)b;
}
void backtrack(int* nums, int numSize, int** ans, int* ansSize, bool* vis, int* row, int idx) {
if (idx == numSize) {
int *tmp = malloc(sizeof(int) * numSize);
memcpy(tmp, row, sizeof(int) * numSize);
ans[(*ansSize)++] = tmp;
return;
}
for (int i = 0; i < numSize; ++i) {
if (vis[i] || (i > 0 && nums[i] == nums[i - 1] && !vis[i - 1])) {
continue;
}
row[idx] = nums[i];
vis[i] = true;
backtrack(nums, numSize, ans, ansSize, vis, row, idx + 1);
vis[i] = false;
}
}
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int** permuteUnique(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
int** ans = malloc(sizeof(int*) * 2001);
int* row = malloc(sizeof(int) * numsSize);
bool* vis = malloc(sizeof(bool) * numsSize);
memset(vis, false, sizeof(bool) * numsSize);
qsort(nums, numsSize, sizeof(int), cmp);
*returnSize = 0;
backtrack(nums, numsSize, ans, returnSize, vis, row, 0);
*returnColumnSizes = malloc(sizeof(int) * (*returnSize));
for (int i = 0; i < *returnSize; i++) {
(*returnColumnSizes)[i] = numsSize;
}
return ans;
}
python
class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
def backtrack(nums: List[int], ans: List[List[int]], vis: List[bool], row: List[int]):
if len(row) == len(nums):
ans.append(row.copy())
return
for i in range(len(nums)):
if not vis[i]:
if i > 0 and nums[i] == nums[i - 1] and not vis[i - 1]:
continue
row.append(nums[i])
vis[i] = True
backtrack(nums, ans, vis, row)
row.pop()
vis[i] = False
nums.sort()
ans = []
backtrack(nums, ans, [False] * len(nums), [])
return ans
java
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
Arrays.sort(nums);
backtrack(nums, ans, new boolean[nums.length], new LinkedList<>());
return ans;
}
private void backtrack(int[] nums, List<List<Integer>> ans, boolean[] vis, Deque<Integer> row) {
if (row.size() == nums.length) {
ans.add(new ArrayList<>(row));
return;
}
for (int i = 0; i < nums.length; ++i) {
if (vis[i] || (i > 0 && nums[i] == nums[i - 1] && !vis[i - 1])) {
continue;
}
row.push(nums[i]);
vis[i] = true;
backtrack(nums, ans, vis, row);
row.pop();
vis[i] = false;
}
}
}
Thank you very much for reading this article~
Welcome to [Like][Favorite][Comment]~It
is not difficult to give up, but it must be cool to persevere~
I hope we all can make a little progress every day~
This article is written by the white hat of the second master : https://le -yi.blog.csdn.net/blog original~