Algorithm leetcode|47. Full Arrangement II (rust punches hard)



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~


Guess you like

Origin blog.csdn.net/leyi520/article/details/130220484