Binary Search Tree - Javascript - Distance between two nodes - binary-search-tree

Given a Binary Search Tree and two nodes, n1 and n2, write a function that finds the distance between the two nodes.
Example: The distance between the nodes 4 and 10 is 4. The distance between the nodes 8 and 10 is 1. The distance between the nodes 1 and 14 is 4.
class Node {
constructor(data) {
this.data = data;
this.left = null;
this.right = null;
}
}
class BinarySearchTree {
constructor() {
this.root = null;
}
So far this is all I have, am not sure how to go about finding the distance between nodes.

Related

problems with index of array

I'm writing a function that allows you to remove certain numbers from an int arraylist.
My code
for (i in 1 until 4) {
divider = setDivider(i)
for(index in 0 until numbers.size){
if(index <= numbers.size){
if (numbers[index] % divider == 0 && !isDone) {
numbers.removeAt(index)
}
}else{
isDone = true
}
}
if(isDone)
break
}
the function to set the divider
fun setDivider(divider: Int): Int {
when (divider) {
1 -> return 2
2 -> return 3
3 -> return 5
4 -> return 7
}
return 8
}
I do not know why the ide is giving me the error Index 9 out of bounds for length 9.
Author explained in the comments that the goal is to remove all numbers that are divisible by 2, 3, 5 and 7.
It can be achieved much easier by utilizing ready to use functions from stdlib:
val dividers = listOf(2, 3, 5, 7)
numbers.removeAll { num ->
dividers.any { num % it == 0 }
}
It removes elements that satisfy the provided condition (is divisible) for any of provided dividers.
Also, it is often cleaner to not modify a collection in-place, but to create an entirely new collection:
val numbers2 = numbers.filterNot { num ->
dividers.any { num % it == 0 }
}

What's time complexity of following modified bucket sort solution

It's kind of bucket sort algorithm, trying to get K nearest locations from point (0,0). This is being done by calculating distances of these locations and bucketing them based on distance. If two locations are at equal distance then priority given to location with closet x and then y(if x values are same)
What is time complexity of following solution?
O(NlogN) or O(KNlogN) or anything else
// java
Input: int k, List<Location>
Output: List<Location>
public class Location {
//constructor x and y
int x;
int y;
//get
//set
//hashcode and equals
}
public class Solution {
public List<Location> returnKNearestLocation(int k, List<Location> locations) {
Map<Float, Set<Location>> map = new TreeMap<>();
for(Location loc: locations) {
float dist = calculateDistance(new Location(0,0), loc);
List<Location> temp = map.getOrDefault(dist, new HashSet());
temp.add(loc);
map.put(temp);
}
List<Location> result = new ArrayList<>();
int size = k;
while(size > 0) {
for(Float key : map.keySet()) {
Set<Location> loc = map.get(key);
Collection.sort(loc, p1, p2 -> {
return p1.x.equals(p2.x)? p1.y.compare(p2.y) : p1.x.compare(p2.x);
});
for(Location currLoc : loc) {
result.add(currLoc);
if(result.size() == k) {
return result;
}
}
size = size - loc.size();
}
}
return result;
}
private float calculateDistance(Location p, Location q) {
// calculate distance Math.sqrt((P.x - Q.x)^2 + (P.y - Q.y)^2)
}
}
I'd say O(N*log(N)).
Assuming float dist = calculateDistance(new Location(0,0), loc) is O(1).
Implementations of put() and getOrDefault() in a TreeMap are O(log(N)). Other implementations offer O(1). I'd take a look at HashMap.
Implementation of add in a HashSet is O(1) (amortized).
Implementation of add in an ArrayList is O(1) (amortized)
BucketSort has a worst-case of O(N^2), in the case that all items are placed in the same bucket.
I'd take a look at HashMap instead of TreeMap.
So, assuming I'm not wrong:
The first loop (foreach loc) has a complexity of O(N*log(N)).
The second loop (while size > 0) is O(N*log(N)).
Assuming all locations are placed in the same bucket, we'll sort all the items (O(N*log(N))).
Then we'll iterate through the first K elements, and add to result -- this takes O(K) < O(N).

How to merge node in yaml-cpp

I have two node object, like this:
school:
grade:
class:
name: bob
school:
grade:
class:
age: 18
I want to merge it, the result like this:
school:
grade:
class:
name: bob
age: 18
How to merge it? when the node size and depth do not kown.
Here is my attempt:
#include <yaml-cpp/yaml.h>
inline const YAML::Node & cnode(const YAML::Node &n) {
return n;
}
YAML::Node merge_nodes(YAML::Node a, YAML::Node b)
{
if (!b.IsMap()) {
// If b is not a map, merge result is b, unless b is null
return b.IsNull() ? a : b;
}
if (!a.IsMap()) {
// If a is not a map, merge result is b
return b;
}
if (!b.size()) {
// If a is a map, and b is an empty map, return a
return a;
}
// Create a new map 'c' with the same mappings as a, merged with b
auto c = YAML::Node(YAML::NodeType::Map);
for (auto n : a) {
if (n.first.IsScalar()) {
const std::string & key = n.first.Scalar();
auto t = YAML::Node(cnode(b)[key]);
if (t) {
c[n.first] = merge_nodes(n.second, t);
continue;
}
}
c[n.first] = n.second;
}
// Add the mappings from 'b' not already in 'c'
for (auto n : b) {
if (!n.first.IsScalar() || !cnode(c)[n.first.Scalar()]) {
c[n.first] = n.second;
}
}
return c;
}
For non-scalar keys I have opted to ignore node equivalence. Please note that this version does not modify a. It returns a new map c which is a merge of b into a. Values from b will replace identically keyed non-map values from a in the c map.
I found an issue with md5i's answer that it doesn't merge the second node's unique sub nodes. My fix was calling the function again in the for loop of node b (which I renamed the override node). I also made everything const, because I'm not editing anything here, and so I don't have to cast it. I'm also reinforcing the fact the second node is overriding the other.
const YAML::Node mergeNodes(const YAML::Node& defaultNode, const YAML::Node& overrideNode)
{
if (!overrideNode.IsMap()) {
// If overrideNode is not a map, merge result is overrideNode, unless overrideNode is null
return overrideNode.IsNull() ? defaultNode : overrideNode;
}
if (!defaultNode.IsMap()) {
// If defaultNode is not a map, merge result is overrideNode
return overrideNode;
}
if (!defaultNode.size()) {
return YAML::Node(overrideNode);
}
// Create a new map 'newNode' with the same mappings as defaultNode, merged with overrideNode
auto newNode = YAML::Node(YAML::NodeType::Map);
for (auto node : defaultNode) {
if (node.first.IsScalar()) {
const std::string& key = node.first.Scalar();
if (overrideNode[key]) {
newNode[node.first] = mergeNodes(node.second, overrideNode[key]);
continue;
}
}
newNode[n.first] = node.second;
}
// Add the mappings from 'overrideNode' not already in 'newNode'
for (auto node : overrideNode) {
if (!node.first.IsScalar()) {
const std::string& key = node.first.Scalar();
if (defaultNode[key]) {
newNode[node.first] = mergeNodes(defaultNode[key], node.second);
continue;
}
}
newNode[node.first] = node.second;
}
return YAML::Node(newNode);
}
This will probably not do the N thingy any favours, but it will take the nodes from node b/overrideNode even if they have no instance in node a/defaultNode.

what's the stack space of this code?

The question is to check if a Tree is a valid BST. There are two recursive method to solve. I think their space complexity both are O(logN), N is the number of TreeNode, so logN is actually the height of tree. But in a solution book, it said the stack space is O(N), I can't figure out. Could anyone help me? Thanks!
public class Solution {
public boolean isValidBST(TreeNode root) {
return isValidBST(root, null, null);
}
private boolean isValidBST(TreeNode x, Integer min, Integer max) {
return x == null || (min == null || x.val > min) && (max == null || x.val < max) &&
isValidBST(x.left, min, x.val) && isValidBST(x.right, x.val, max);
}
}
public class Solution {
private TreeNode prev;
public boolean isValidBST(TreeNode root) {
prev = null;
return isMonotonicIncreasing(root);
}
private boolean isMonotonicIncreasing(TreeNode p) {
if (p == null) return true;
if (isMonotonicIncreasing(p.left)) {
if (prev != null && p.val <= prev.val) return false;
prev = p;
return isMonotonicIncreasing(p.right);
}
return false;
}
}
Space requirements will be O(h), where h is the height of the tree.
Log(n) is the best case for this code when the tree is balanced.
But in case of skewed trees the space complexity will be O(n) i.e. linear.
For example, for following trees, the code will take Exactly S(n) space:
1 5
2 4
3 3
4 2
5 1

Binary Search Trees, Breadth First Traversal

I have been sitting on this one for some time. In the Binary Search Tree, when you do a breadth first traversal There is this one line of code that I dont know what it does. In the textbook I am using the code is as follows.
public void breadthFirst()
{
BSTNode<T> p = root;
Queue<BSTNode<T>> queue = new Queue<BSTNode<T>>();
if(p != null)
{
queue.enqueue(p);
while(!queue.isEmpty())
{
**p = queue.dequeue();**
visit(p);
if(p.left != null)
{
queue.enqueue(p.left);
}
if(p.right != null)
{
queue.enqueue(p.right);
}
}
}
}
The Queue contains nodes that we have to visit. Before when we visit a node we take it out of the queue (dequeue) so that it will not be visited again.