2019-01-13 Daily Challenge
What I've done today is Lexicographic permutations in Rust and Unique Binary Search Trees II in JavaScript.
Math
Problem
Lexicographic permutations
Problem 24
A permutation is an ordered arrangement of objects. For example, 3124 is one possible permutation of the digits 1, 2, 3 and 4. If all of the permutations are listed numerically or alphabetically, we call it lexicographic order. The lexicographic permutations of 0, 1 and 2 are:
012 021 102 120 201 210
What is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9?
Solution
I've done it with javascript in 2019-01-03 Daily Challenge, so what I need to do is just translate it into Rust.
Implementation
use std::vec::Vec;
fn main() {
for i in nth_permutation(3, 3) {
println!("{}", i);
}
println!("");
for i in nth_permutation(4, 9) {
print!("{}", i);
}
println!("");
for i in nth_permutation(10, 1_000_000) {
print!("{}", i);
}
}
fn nth_permutation(n: i32, mut k: i64) -> Vec<i32> {
k -= 1;
let mut fac: Vec<i64> = [1].to_vec();
let mut ans: Vec<i32> = Vec::new();
let mut used: Vec<bool> = [false].to_vec();
for i in 1i64..(n as i64) {
let tmp = fac[i as usize - 1]*i;
fac.push(tmp);
used.push(false);
}
let mut cur = n-1;
while cur >= 0 {
let mut index = k/fac[cur as usize];
k %= fac[cur as usize];
for i in 0..used.len() {
if !used[i] {
if index > 0 {
index -= 1;
}else{
ans.push(i as i32);
used[i] = true;
break;
}
}
}
cur -= 1;
}
return ans;
}
Algorithm
Problem
95. Unique Binary Search Trees II
Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1 ... n.
Example:
Input: 3
Output:
[
[1,null,3,2],
[3,2,null,1],
[3,1,null,null,2],
[2,1,3],
[1,null,2,null,3]
]
Explanation:
The above output corresponds to the 5 unique BST's shown below:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
Solution
Because it is BST, so when we determine one root, we will known what's on its left and what's on right. So we could do it recursively.
Because recursive process will go through many repeated tree nodes(like recursive fibonacci function), so we could memorize it.
Implementation
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {number} n
* @return {TreeNode[]}
*/
var generateTrees = function(n) {
if(n===0) return [];
const map = new Map();
return generateTreess(1,n+1,map);
};
/**
* Interval is left-closed right-opened
* @param {number} l
* @param {number} r
* @param {Map} map
* @return {TreeNode[]}
*/
function generateTreess(l,r,map){
if(l===r) return [null];
if(map.has(l)&&map.get(l).has(r)){
return map.get(l).get(r);
}
let trees = [];
for(let i = l; i < r; ++i){
const left = generateTreess(l,i,map);
const right = generateTreess(i+1,r,map);
for(let j = 0; j < left.length; ++j){
for(let k = 0; k < right.length; ++k){
const node = new TreeNode(i);
node.left = left[i];
node.right = right[k];
trees.push(node);
}
}
}
if(!map.has(l)){
map.set(l,new Map());
}
map.get(l).set(r,trees);
return trees;
}