Binary number & Base N number &Permutation&N queens

Jimmy (xiaoke) Shen
3 min readFeb 21, 2020

--

I’d like to build the connection between Permutation and N queens problem.

Base N number system with N “BITs”. “BITs” here means symbols.

Assume N queens are putted column by column

Base N number with N “BIT” = N queens without any constraints.

Permutation = N queens with row constraints but no diagonal constraints.

N queens = N queens (it has both row and diagonal constraints)

Leet code 46 permutations codes.

Solution 1 naively enumerating

C++

An ugly recursion code

/*
jimmy shen
02/20/2020
A code to implement the naive o(n^n) permutation algorithm.
runtime 232 ms
time complexity O(n^n)
space complexity O(n^n) as we introduce an extra container productions
*/
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
// productions may have repeatings. It is supposed to have n^n elements.
vector<vector<int>> productions={{}};
vector<vector<int>> permutations;
// iteratively generate productions.
for (int i=0;i<nums.size();++i){
vector<vector<int>> new_productions;
for(auto &num:nums){
for(auto& prod:productions){
vector<int> new_prod = prod;
new_prod.push_back(num);
new_productions.push_back(new_prod);
}
}
productions = new_productions;
}
// generate the final results by removing results which has repeating.
for(auto&prod:productions){
// compare the size of set s to nums.size(). If s.size()==nums.size(), there is no repeating.
unordered_set<int> s(prod.begin(), prod.end());
if (s.size()==nums.size()){
vector<int> permu(prod.begin(), prod.end());
permutations.push_back(permu);
}
}
return permutations;
}
};

A OK iteration code

/*
jimmy shen
02/20/2020
A code to implement the naive o(n^n) permutation algorithm.
runtime 72 ms
time complexity O(n^n)
space complexity O(n^n) as we introduce an extra container productions
*/
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
// productions may have repeatings. It is supposed to have n^n elements.
vector<vector<int>> productions={{}};
vector<vector<int>> permutations;
// iteratively generate productions.
//productions = product(nums, 0);
for (int i=0;i<nums.size();++i){
vector<vector<int>> new_productions;
for(auto &num:nums){
for(auto& prod:productions){
vector<int> new_prod = prod;
new_prod.push_back(num);
new_productions.push_back(new_prod);
}
}
productions = new_productions;
}
// generate the final results by only using valid results. Valid here means no repeating.
for(auto&prod:productions){
// compare the size of set s to nums.size(). If s.size()==nums.size(), there is no repeating.
unordered_set<int> s(prod.begin(), prod.end());
if (s.size()==nums.size()){
vector<int> permu(prod.begin(), prod.end());
permutations.push_back(permu);
}
}
return permutations;
}
};

A better recursion code

/*
jimmy shen
02/20/2020
A code to implement the naive o(n^n) permutation algorithm.
runtime 208 ms
time complexity O(n^n)
space complexity O(n)
*/
class Solution {
vector<vector<int>> permutations_;
public:
bool has_repeat(vector<int>&numbers){
unordered_set<int> s(numbers.begin(), numbers.end());
return s.size()!=numbers.size();
}

void permute(vector<int>&nums, vector<int>&this_permu, int low){
const int n = nums.size();
vector<int> temp = this_permu;
// if size of this_permu reach to n and it has no repeating, collect this result.
if(temp.size()==n && !has_repeat(temp)){
permutations_.push_back(temp);
return;
}
for( int j = low; j < n; ++j){
for(auto &num:nums){
temp.push_back(num);
permute(nums, temp, j+1);
temp.pop_back();
}
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<int> this_permu;
permute(nums, this_permu, 0);
return permutations_;
}
};

A N queens similar approach

/*
jimmy shen
02/20/2020
A code to implement the o(n!) permutation algorithm with earlier pruning. It is similar to the N queens problem. Permutation is like N queens problem without diagonal constraints.
runtime 16 ms
time complexity O(n^n)
space complexity O(n) as we have visited
*/
class Solution {
vector<vector<int>> permutations_;
public:

void permute(vector<int>&nums, vector<int>&this_permu, int low, vector<int>&visited){
const int n = nums.size();
vector<int> temp = this_permu;
// if size of this_permu reach to n and it has no repeating, collect this result.
if(temp.size()==n){
permutations_.push_back(temp);
return;
}
for( int j = low; j < n; ++j){
for(int i=0; i<n; ++i){
int num = nums[i];
if(!visited[i]){
visited[i] = true;
temp.push_back(num);
permute(nums, temp, j+1, visited);
temp.pop_back();
visited[i] = false;
}
}
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<int> this_permu, visited(nums.size());
permute(nums, this_permu, 0, visited);
return permutations_;
}
};

Python

"""
jimmy shen
02/20/2020
A code to implement the naive o(n^n) permutation algorithm.
runtime 72 ms
time complexity O(n^n)
space complexity O(n)
"""
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
return [perm for perm in itertools.product(*[nums]*len(nums)) if len(perm)==len(set(perm))]

Other solutions.

https://medium.com/@jim.morris.shen/permutations-b7f6054f67f9?source=friends_link&sk=9305530d7ddb7c61147fca1a7567ecab

--

--

No responses yet