65. Permutations
nums has distinct integers. Return all permutations, 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]]Hint 1
At each position, try every unused number.
Hint 2
A used array tracks what is already in the path.
Approach 1: Backtracking with used[] ✅
Build permutations position by position.
⏱ Time O(n · n!)💾 Space O(n)
Reference solution for Backtracking with used[] (time O(n · n!), space O(n)). Each solution passes every test in all four languages.
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
res, path, used = [], [], [False] * len(nums)
def backtrack():
if len(path) == len(nums):
res.append(path[:])
return
for i, x in enumerate(nums):
if used[i]:
continue
used[i] = True
path.append(x)
backtrack()
path.pop()
used[i] = False
backtrack()
return resclass Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
backtrack(nums, new boolean[nums.length], new ArrayList<>(), res);
return res;
}
private void backtrack(int[] nums, boolean[] used, List<Integer> path, List<List<Integer>> res) {
if (path.size() == nums.length) { res.add(new ArrayList<>(path)); return; }
for (int i = 0; i < nums.length; i++) {
if (used[i]) continue;
used[i] = true; path.add(nums[i]);
backtrack(nums, used, path, res);
path.remove(path.size() - 1); used[i] = false;
}
}
}class Solution {
void backtrack(vector<int>& nums, vector<bool>& used, vector<int>& path, vector<vector<int>>& res) {
if (path.size() == nums.size()) { res.push_back(path); return; }
for (int i = 0; i < (int)nums.size(); i++) {
if (used[i]) continue;
used[i] = true; path.push_back(nums[i]);
backtrack(nums, used, path, res);
path.pop_back(); used[i] = false;
}
}
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> res;
vector<int> path;
vector<bool> used(nums.size(), false);
backtrack(nums, used, path, res);
return res;
}
};function permute(nums) {
const res = [], path = [], used = new Array(nums.length).fill(false);
const backtrack = () => {
if (path.length === nums.length) { res.push([...path]); return; }
for (let i = 0; i < nums.length; i++) {
if (used[i]) continue;
used[i] = true; path.push(nums[i]);
backtrack();
path.pop(); used[i] = false;
}
};
backtrack();
return res;
}Try solving it yourself first. Interviewers care more about how you explain the approach than about the finished code.
Watch the core idea of this problem step by step. Change the input and press Visualize.
Explained in the lesson Recursion & Backtracking.
Run your code to see results here.