[algorithm] sword finger Offer II 083. Full Permutation without repeated element set 46. Full Permutation (Multilingual Implementation)

Thank you very much for reading this article~
Welcome[ 👍 [like][ ⭐ Collection][ 📝 [comments]~
It's not hard to give up, but it must be cool to insist~
I hope all of us can make a little progress every day~
This paper consists of White hat of the second leader: https://le-yi.blog.csdn.net/ Blog originality~

Sword finger Offer II 083. Full arrangement without repeated element set | 46. Full arrangement:

Given an integer array nums without duplicate numbers, returns all possible permutations. You can return answers in any order.

Example 1

Input:
	nums = [1,2,3]

Output:
	[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

Example 2

Input:
	nums = [0,1]

Output:
	[[0,1],[1,0]]

Example 3

Input:
	nums = [1]
	
Output:
	[[1]]

Tips

  • 1 <= nums.length <= 6
  • -10 <= nums[i] <= 10
  • All integers in nums are different from each other

analysis

  • This algorithm problem adopts recursion, and the backtracking method is relatively simple. If anyone has to use circular non recursion, the second leader will admire it.
  • The prompt says that each number is different, so we can consider the full arrangement as the different arrangement of the number position or the subscript of the array. Because the numbers are different, we don't have to care about what each number is.
  • We can open up a single space to store the middle arrangement, so that we need to be able to judge whether a number has been selected. We can use the hash table to store the current arrangement results, and then see whether it contains the current number, but this seems to be inefficient.
  • The number of each location is different, so we can directly store whether the number of a location is used.
  • You can directly use a Boolean array to store the accessed location, but the prompt says that the number of numbers is up to 6, so we can use up to 6 binary bits to represent the used and unused numbers. An int variable is enough. We use the binary bit change of this int variable to correspond to the used and unused numbers.
  • You can also directly simulate the arrangement in the original array by exchange. Isn't it a full arrangement that each number is arranged once in all positions? First rotate to the first position, then rotate to the second position, and so on.

Problem solution

java

No exchange

class Solution {
    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> ans = new ArrayList<>();
		dfs(nums, new ArrayList<>(nums.length), 0, ans);
		return ans;
	}
	
	private void dfs(int[] nums, List<Integer> row, int flag, List<List<Integer>> ans) {
		if (row.size() == nums.length) {
			ans.add(new ArrayList<>(row));
			return;
		}
		for (int i = 0; i < nums.length; ++i) {
			if (((flag >> i) & 1) == 0) {
				row.add(nums[i]);
				dfs(nums, row, flag | (1 << i), ans);
				row.remove(row.size() - 1);
			}
		}
	}
}

Use exchange mode

class Solution {
    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> ans = new ArrayList<>();
		backtrack(nums, 0, ans);
		return ans;
	}

	private void backtrack(int[] nums, int cur, List<List<Integer>> ans) {
		if (cur == nums.length) {
			ans.add(Arrays.stream(nums).boxed().collect(Collectors.toList()));
			return;
		}
		// The current position remains the same, then the next one
		backtrack(nums, cur + 1, ans);
		// Change one of the back to the current position
		for (int i = cur + 1; i < nums.length; ++i) {
			swap(nums, cur, i);
			backtrack(nums, cur + 1, ans);
			swap(nums, cur, i);
		}
	}

	private void swap(int[] nums, int a, int b) {
		nums[a] ^= nums[b];
		nums[b] ^= nums[a];
		nums[a] ^= nums[b];
	}
}

c

/**
 * 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** permute(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    *returnSize = numsSize;
    for (int i = 2; i < numsSize; ++i) {
        *returnSize *= i;
    }

    int **ans = (int **) malloc(sizeof(int *) * (*returnSize));
    *returnColumnSizes = (int *) malloc(sizeof(int) * (*returnSize));
    for (int i = 0; i < *returnSize; ++i) {
        ans[i] = (int *) malloc(sizeof(int) * numsSize);
        (*returnColumnSizes)[i] = numsSize;
    }

    int ansSize = 0;

    backtrack(nums, numsSize, 0, ans, &ansSize);

    return ans;
}

void backtrack(int* nums, int numsSize, int cur, int **ans, int *ansSize) {
    if (cur == numsSize) {
        for (int i = 0; i < numsSize; ++i) {
            ans[*ansSize][i] = nums[i];
        }
        *ansSize += 1;
        return;
    }
    // The current position remains the same, then the next one
    backtrack(nums, numsSize, cur + 1, ans, ansSize);
    // Change one of the back to the current position
    for (int i = cur + 1; i < numsSize; ++i) {
        swap(nums, cur, i);
        backtrack(nums, numsSize, cur + 1, ans, ansSize);
        swap(nums, cur, i);
    }
}

void swap(int* nums, int a, int b) {
    nums[a] ^= nums[b];
    nums[b] ^= nums[a];
    nums[a] ^= nums[b];
}

c++

class Solution {
private:
    void backtrack(vector<int> &nums, int cur, vector<vector<int>> &ans) {
        if (cur == nums.size()) {
            ans.push_back(nums);
            return;
        }
        // The current position remains the same, then the next one
        backtrack(nums, cur + 1, ans);
        // Change one of the back to the current position
        for (int i = cur + 1; i < nums.size(); ++i) {
            swap(nums[cur], nums[i]);
            backtrack(nums, cur + 1, ans);
            swap(nums[cur], nums[i]);
        }
    }
public:
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int>> ans;

        backtrack(nums, 0, ans);

        return ans;
    }
};

python

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        n = len(nums)
        ans = []

        def backtrack(cur: int) -> None:
            if cur == n:
                ans.append(nums[:])
                return
            # The current position remains the same, then the next one
            backtrack(cur + 1)
            # Change one of the back to the current position
            for i in range(cur + 1, n):
                nums[cur], nums[i] = nums[i], nums[cur]
                backtrack(cur + 1)
                nums[cur], nums[i] = nums[i], nums[cur]

        backtrack(0)
        return ans
        

go

func permute(nums []int) [][]int {
    n := len(nums)
	var ans [][]int

	var backtrack func(cur int)
	backtrack = func(cur int) {
		if cur == n {
			ans = append(ans, append([]int{}, nums...))
			return
		}
		// The current position remains the same, then the next one
		backtrack(cur + 1)
		// Change one of the back to the current position
		for i := cur + 1; i < n; i++ {
			nums[cur], nums[i] = nums[i], nums[cur]
			backtrack(cur + 1)
			nums[cur], nums[i] = nums[i], nums[cur]
		}
	}

	backtrack(0)

	return ans
}

rust

impl Solution {
    pub fn permute(mut nums: Vec<i32>) -> Vec<Vec<i32>> {
        let mut ans = Vec::new();

        Solution::backtrack(&mut nums, 0, &mut ans);

        ans
    }

    fn backtrack(nums: &mut Vec<i32>, cur: usize, ans: &mut Vec<Vec<i32>>) {
        if cur == nums.len() {
            ans.push(nums.clone());
            return;
        }
        // The current position remains the same, then the next one
        Solution::backtrack(nums, cur + 1, ans);
        // Change one of the back to the current position
        (cur + 1..nums.len()).for_each(|i| {
            nums.swap(cur, i);
            Solution::backtrack(nums, cur + 1, ans);
            nums.swap(cur, i);
        });
    }
}

Original title portal: https://leetcode-cn.com/problems/VvJkup/

Original title portal: https://leetcode-cn.com/problems/permutations/

Tags: Python Java C Go Rust

Posted on Sat, 06 Nov 2021 20:43:52 -0400 by FireWhizzle