What is the size above depth of BST - java

This is what I have so far. I need to computes the size of the tree above at depth k.
public static int above(Node t, int k) {
if (t == null) { return 0; }
if (t.key > k)
return (above(t.left, k - 1) + above(t.right, k - 1) + 1);
else {
return above(t.left, k - 1) + above(t.right, k - 1);
}
}
EDIT: This code works and computes the size of the tree at depth k.
public static int at(Node t, int k) {
if(t == null) return 0;
if(k == 0) return 1;
return at(t.left, k - 1) + at(t.right, k - 1);
}

I would of thought something more like this would do it... but maybe I don't understand the problem correctly.
public static int above(Node t, int k) {
if (t == null) { return 0; }
if (k > 0) {
return (above(t.left, k - 1) + above(t.right, k - 1) + 1);
} else {
return 1;
}
}

This code computes the tree size till depth k where root is at depth 1.
static int depth=0;
static int tree_size=0,k=3;
private static void inorder(Node head) {
if(head!=null){
depth++;
inorder(head.left);
if(depth<=k)
tree_size++;
inorder(head.right);
depth--;
}
}

Related

How can I show the value of array with the Binary Search Tree of Comparison?

I going to do searching the value in the array, did I need to create a method to handle it? For example, the array logged 32,21,13,44,22, and I going to find 22 of the comparison. How can I implement this?
public class binarySearch {
public static void main(String [] args) {
int i = binarySearch(0, new int[]{32,21,13,44,22});
System.out.println("Iterations: " + i);
}
public static int binarySearch(int key, int[] array) {
int left = 0;
int mid;
int right = array.length - 1;
int i = 0;
while (left <= right) {
mid = (left + right) / 2;
int comp = Integer.compare(key, array[mid]);
i++;
if (comp < 0) {
right = mid - 1;
} else if (comp > 0) {
left = mid + 1;
} else {
break; // success
}
}
return i;
}
}
My final answer is here. May help you all in the future.
public static int binarySearch(int key, int[] array) {
int left = 0;
int mid;
int right = array.length - 1;
int i = 0;
while (left <= right) {
mid = (left + right) / 2;
int comp = Integer.compare(key, array[mid]);
i++;
if (comp < 0) {
right = mid - 1;
} else if (comp > 0) {
left = mid + 1;
} else {
break; // success
}
}
return i;
}
If you have shuffled array, all you can do is go through an array and find your number.
BinarySearch works only with sorted array. I think your solution could look like this:
public static int binarySearch(int[] arr, int key) {
Arrays.sort(arr);
return Arrays.binarySearch(arr, key);
}

perfect squares leetcode - recursive solution with memoization

Trying to solve this problem with recursion and memoization but for input 7168 I'm getting wrong answer.
public int numSquares(int n) {
Map<Integer, Integer> memo = new HashMap();
List<Integer> list = fillSquares(n, memo);
if (list == null)
return 1;
return helper(list.size()-1, list, n, memo);
}
private int helper(int index, List<Integer> list, int left, Map<Integer, Integer> memo) {
if (left == 0)
return 0;
if (left < 0 || index < 0)
return Integer.MAX_VALUE-1;
if (memo.containsKey(left)) {
return memo.get(left);
}
int d1 = 1+helper(index, list, left-list.get(index), memo);
int d2 = 1+helper(index-1, list, left-list.get(index), memo);
int d3 = helper(index-1, list, left, memo);
int d = Math.min(Math.min(d1,d2), d3);
memo.put(left, d);
return d;
}
private List<Integer> fillSquares(int n, Map<Integer, Integer> memo) {
int curr = 1;
List<Integer> list = new ArrayList();
int d = (int)Math.pow(curr, 2);
while (d < n) {
list.add(d);
memo.put(d, 1);
curr++;
d = (int)Math.pow(curr, 2);
}
if (d == n)
return null;
return list;
}
I'm calling like this:
numSquares(7168)
All test cases pass (even complex cases), but this one fails. I suspect something is wrong with my memoization but cannot pinpoint what exactly. Any help will be appreciated.
You have the memoization keyed by the value to be attained, but this does not take into account the value of index, which actually puts restrictions on which powers you can use to attain that value. That means that if (in the extreme case) index is 0, you can only reduce what is left with one square (1²), which rarely is the optimal way to form that number. So in a first instance memo.set() will register a non-optimal number of squares, which later will get updated by other recursive calls which are pending in the recursion tree.
If you add some conditional debugging code, you'll see that map.set is called for the same value of left multiple times, and with differing values. This is not good, because that means the if (memo.has(left)) block will execute for cases where that value is not guaranteed to be optimal (yet).
You could solve this by incorporating the index in your memoization key. This increases the space used for memoization, but it will work. I assume you can work this out.
But according to Lagrange's four square theorem every natural number can be written as the sum of at most four squares, so the returned value should never be 5 or more. You can shortcut the recursion when you get passed that number of terms. This reduces the benefit of using memoization.
Finally, there is a mistake in fillSquares: it should add n itself also when it is a perfect square, otherwise you'll not find solutions that should return 1.
Not sure about your bug, here is a short dynamic programming Solution:
Java
public class Solution {
public static final int numSquares(
final int n
) {
int[] dp = new int[n + 1];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0] = 0;
for (int i = 1; i <= n; i++) {
int j = 1;
int min = Integer.MAX_VALUE;
while (i - j * j >= 0) {
min = Math.min(min, dp[i - j * j] + 1);
++j;
}
dp[i] = min;
}
return dp[n];
}
}
C++
// Most of headers are already included;
// Can be removed;
#include <iostream>
#include <cstdint>
#include <vector>
#include <algorithm>
// The following block might slightly improve the execution time;
// Can be removed;
static const auto __optimize__ = []() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
return 0;
}();
#define MAX INT_MAX
using ValueType = std::uint_fast32_t;
struct Solution {
static const int numSquares(
const int n
) {
if (n < 1) {
return 0;
}
static std::vector<ValueType> count_perfect_squares{0};
while (std::size(count_perfect_squares) <= n) {
const ValueType len = std::size(count_perfect_squares);
ValueType count_squares = MAX;
for (ValueType index = 1; index * index <= len; ++index) {
count_squares = std::min(count_squares, 1 + count_perfect_squares[len - index * index]);
}
count_perfect_squares.emplace_back(count_squares);
}
return count_perfect_squares[n];
}
};
int main() {
std::cout << std::to_string(Solution().numSquares(12) == 3) << "\n";
return 0;
}
Python
Here we can simply use lru_cache:
class Solution:
dp = [0]
#functools.lru_cache
def numSquares(self, n):
dp = self.dp
while len(dp) <= n:
dp += min(dp[-i * i] for i in range(1, int(len(dp) ** 0.5 + 1))) + 1,
return dp[n]
Here are LeetCode's official solutions with comments:
Java: DP
class Solution {
public int numSquares(int n) {
int dp[] = new int[n + 1];
Arrays.fill(dp, Integer.MAX_VALUE);
// bottom case
dp[0] = 0;
// pre-calculate the square numbers.
int max_square_index = (int) Math.sqrt(n) + 1;
int square_nums[] = new int[max_square_index];
for (int i = 1; i < max_square_index; ++i) {
square_nums[i] = i * i;
}
for (int i = 1; i <= n; ++i) {
for (int s = 1; s < max_square_index; ++s) {
if (i < square_nums[s])
break;
dp[i] = Math.min(dp[i], dp[i - square_nums[s]] + 1);
}
}
return dp[n];
}
}
Java: Greedy
class Solution {
Set<Integer> square_nums = new HashSet<Integer>();
protected boolean is_divided_by(int n, int count) {
if (count == 1) {
return square_nums.contains(n);
}
for (Integer square : square_nums) {
if (is_divided_by(n - square, count - 1)) {
return true;
}
}
return false;
}
public int numSquares(int n) {
this.square_nums.clear();
for (int i = 1; i * i <= n; ++i) {
this.square_nums.add(i * i);
}
int count = 1;
for (; count <= n; ++count) {
if (is_divided_by(n, count))
return count;
}
return count;
}
}
Java: Breadth First Search
class Solution {
public int numSquares(int n) {
ArrayList<Integer> square_nums = new ArrayList<Integer>();
for (int i = 1; i * i <= n; ++i) {
square_nums.add(i * i);
}
Set<Integer> queue = new HashSet<Integer>();
queue.add(n);
int level = 0;
while (queue.size() > 0) {
level += 1;
Set<Integer> next_queue = new HashSet<Integer>();
for (Integer remainder : queue) {
for (Integer square : square_nums) {
if (remainder.equals(square)) {
return level;
} else if (remainder < square) {
break;
} else {
next_queue.add(remainder - square);
}
}
}
queue = next_queue;
}
return level;
}
}
Java: Most efficient solution using math
Runtime: O(N ^ 0.5)
Memory: O(1)
class Solution {
protected boolean isSquare(int n) {
int sq = (int) Math.sqrt(n);
return n == sq * sq;
}
public int numSquares(int n) {
// four-square and three-square theorems.
while (n % 4 == 0)
n /= 4;
if (n % 8 == 7)
return 4;
if (this.isSquare(n))
return 1;
// enumeration to check if the number can be decomposed into sum of two squares.
for (int i = 1; i * i <= n; ++i) {
if (this.isSquare(n - i * i))
return 2;
}
// bottom case of three-square theorem.
return 3;
}
}

Max Heap MaxHeapify Java Not finishing

Having trouble with the constructor for MaxHeapify when there are more than 2 numbers that need to be ordered. stepping thru the code, it works for the first few and then continues without properly ordering the numbers.
i am not sure why this isn't working, any assistance on which variables or comparisons I seem to be mixing up here would be much appreciated.
public class MaxHeap
{
public int[] heap;
public int index_to_last_element;
protected void maxHeapify(int index)
{
int left = leftchild(index);
int right = rightchild(index);
int largest = index;
if (left < index_to_last_element && left != -1 && heap[left] > heap[index])
largest = left;
if (right < index_to_last_element && right != -1 && heap[right] > heap[largest])
largest = right;
if (largest != index)
{
int temp = heap[index];
heap[index] = heap[largest];
heap[largest] = temp;
maxHeapify(largest);
}
}
public int parent(int pos)
{
return (pos - 1) / 2;
}
public int leftchild(int pos)
{
return 2 * pos + 1;
}
public int rightchild(int pos)
{
return 2 * pos + 2;
}

Generic multi threaded quicksort java

I have been given an assignment to modify quicksort program in such a way so it uses generics and its multi threaded. The problem i have with the code is that it takes longer for the Multi threaded Integer quicksort call to finish, compared to the non-threaded one.
This is my implementation of both - non threaded and multi threaded and I have a problem finding the mistake I have done.
class GenericQuicksort {
private static void swap(Comparable[] array, int i, int j) {
Comparable temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public static Comparable[] quickSort(Comparable[] array) {
return qs(array, 0, array.length - 1);
}
private static Comparable[] qs(Comparable[] array, int left, int righ) {
int i = left;
int j = righ;
Comparable pivot = array[(left + righ) / 2];
do {
while ((array[i].compareTo(pivot) == -1) && (i < righ)) i++;
while ((pivot.compareTo(array[j]) == -1) && (j > left)) j--;
if (i <= j) {
swap(array, i++, j--);
}
} while (i <= j);
if (left < j) qs(array, left, j);
if (i < righ) qs(array, i, righ);
return array;
}
public static Comparable[] quickSortMulti(Comparable[] array) {
GsMultiThread gsMultiThread = new GsMultiThread(array, 0, array.length - 1, 0);
gsMultiThread.start(); //Not needed to start a new thread.
try {
gsMultiThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return array;
}
static class GsMultiThread extends Thread {
Comparable[] array;
int left;
int right;
int ii;
public GsMultiThread(Comparable[] array, int left, int right, int i) {
this.array = array;
this.left = left;
this.right = right;
this.ii = ++i;
}
#Override
public void run() {
int i = left;
int j = right;
Comparable pivot = array[(left + right) / 2];
do {
while ((array[i].compareTo(pivot) == -1) && (i < right)) i++;
while ((pivot.compareTo(array[j]) == -1) && (j > left)) j--;
if (i <= j) {
swap(array, i++, j--);
}
} while (i <= j);
GsMultiThread threada = null;
GsMultiThread threadb = null;
if (left < j) {
if (i > 2) {
qs(array, left, j);
} else {
threada = new GsMultiThread(array, left, j, ii);
threada.start();
}
}
if (i < right) {
if (i > 2) {
qs(array, i, right);
} else {
threadb = new GsMultiThread(array, i, right, ii);
threadb.run();
}
}
try {
if (threada != null)
threada.join();
if (threadb != null)
threadb.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

find the index in a sorted array

it's a basic problem that given a sorted array and a target value, find the index if the target is found. If not, return the index where it would be if it were inserted in order.
Here is my method:
public int searchInsert1(int[] A, int target) {
if (A == null || A.length == 0)
return 0;
return search(A, target, 0, A.length);
}
public int search(int[] a, int target, int s, int e) {
if (s == e)
return s;
int mid = (s + e) / 2;
if (a[mid] == target) {
return mid;
} else if (target < a[mid]) {
return search(a, target, 0, mid - 1);
} else {
return search(a, target, mid, e);
}
}
somehow, it always returns the wrong index value. However, if I change the if else part as the following, it works:
if (a[mid] == target) {
return mid;
} else if (target > a[mid]) {
return search(a, target, mid + 1, e);
} else {
return search(a, target, 0, mid);
}
can anyone help me with it in detail? Thanks so much in advance
Use this method
public int search(int[] a, int target, int s, int e) {
int low = s;
int high = e- 1;
while (low <= high) {
int mid = (low + high) >>> 1;
int midVal = a[mid];
if (midVal < target)
low = mid + 1;
else if (midVal > target)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
}
Your code has errors in these parts:
1. you have set end index wrong, it should be :A.length - 1;
2. your return value in the condition part is wrong,the return value in your "else" part should be: search(a, target, 0, mid+1, e);
Correct code should be:
public int searchInsert1(int[] A, int target) {
if (A == null || A.length == 0)
return 0;
// check if target is larger than the largest value or smaller than the smallest value
if (target < A[0])
return 0;
else if (target > A[A.length-1])
return A.length-1;
return search(A, target, 0, A.length-1);
}
public int search(int[] a, int target, int s, int e) {
if (s == e)
return s;
int mid = (s + e) / 2;
if (a[mid] == target) {
return mid;
} else if (target < a[mid]) {
return search(a, target, 0, mid - 1);
} else {
return search(a, target, mid+1, e);
}
}
Here is my simplest solution in Java
public static int search(int[] a, int target) {
for (int i = 0; i < a.length; i++) {
if (a[i] == target) {
return i;
}
}
return -1;
}

Categories