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);
}
I am new to recursion and binary trees. I am trying to solve this problem on leetcode.
To find maximum sum path is like finding maximum path between any two nodes, that path may or may not pass through the root; except that with max sum path we want to track sum instead of path length.
My algorithm is passing 91/93 test cases and I just can't figure out what I am missing. Can anyone please provide some direction?
class Solution {
private int sum = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
maxPathSumHelper(root);
if(root.left != null){
maxPathSumHelper(root.left);
}
if(root.right != null){
maxPathSumHelper(root.right);
}
return sum;
}
public int maxPathSumHelper(TreeNode root){
if(root == null){
return 0;
}
//check left sum
int leftValue = root.val + maxPathSumHelper(root.left);
if(leftValue > sum){
sum = leftValue;
}
//check right sum
int rightValue = root.val + maxPathSumHelper(root.right);
if(rightValue > sum){
sum = rightValue;
}
//check if root value is greater
if(root.val > sum){
sum = root.val;
}
//check if right and left value is the greatest
if((leftValue + rightValue - (2 * root.val) )+ root.val > sum){
sum = (leftValue + rightValue - (2 * root.val)) + root.val;
}
return Math.max(leftValue, rightValue);
}
}
Try
class Solution {
private int sum = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
maxPathSumHelper(root);
if (root.left != null) {
maxPathSumHelper(root.left);
} else if (root.right != null) {
maxPathSumHelper(root.right);
}
return sum;
}
public int maxPathSumHelper(TreeNode root) {
if (root == null) {
return 0;
}
//check left sum
int leftValue = root.val + maxPathSumHelper(root.left);
if (leftValue > sum) {
sum = leftValue;
}
//check right sum
int rightValue = root.val + maxPathSumHelper(root.right);
if (rightValue > sum) {
sum = rightValue;
}
//check if root value is greater
if (root.val > sum) {
sum = root.val;
}
//check if right and left value is the greatest
if ((leftValue + rightValue - (2 * root.val) ) + root.val > sum) {
sum = (leftValue + rightValue - (2 * root.val)) + root.val;
}
return Math.max(Math.max(leftValue, rightValue), root.val);
}
}
I guess we can a bit simplify our statements here.
This'll simply get accepted:
public final class Solution {
int max;
public final int maxPathSum(final TreeNode root) {
max = Integer.MIN_VALUE;
traverse(root);
return max;
}
private final int traverse(final TreeNode node) {
if (node == null)
return 0;
final int l = Math.max(0, traverse(node.left));
final int r = Math.max(0, traverse(node.right));
max = Math.max(max, l + r + node.val);
return Math.max(l, r) + node.val;
}
}
References
For additional details, please see the Discussion Board which you can find plenty of well-explained accepted solutions in there, with a variety of languages including efficient algorithms and asymptotic time/space complexity analysis1, 2.
i got this problem where i need to return the line which its members bring the biggest sum in matrix, the problem needs to be with recursive methods ( no loops )
i started firstly by finding the biggest sum, but i dont know how to proceed further, please help me
public class MatrixLen {
private int [][] _mat;
public MatrixLen(int sizeRow, int sizeCol)
{
_mat = new int[sizeRow][sizeCol];
Random generator = new Random();
for (int i = 0; i< sizeRow; i++){
for (int j=0; j<sizeCol; j++){
_mat[i][j] = generator.nextInt(20) - 10;
System.out.print(_mat[i][j]+ " ");
}
System.out.println();
}
}
private int SumRow(int i){
return SumRow(i,0);
}
private int SumRow(int i, int j){
if(j>=_mat[i].length) return 0;
return _mat[i][j] + SumRow(i, j+1);
}
public int maxRow(){
if(_mat.length==0) return -1;
return maxRow(0);
}
private int maxRow(int i){
if (i == _mat.length - 1) return SumRow(i); //end case - last row
int max = maxRow (i + 1);
int thisRow = SumRow(i);
return thisRow > max ? thisRow : max;
}
}
You can define a class holding the index of the current row as well as the sum. E.g.
public class IndexSum {
int index;
int sum;
public IndexSum(int index, int sum) {
this.index = index;
this.sum = sum;
}
}
Then in MatrixLen modify maxRow methods to get as argument and also return a IndexSum object. This way, during recursion, you keep track of the sum of a row to compare with other rows, but also of the index of this row.
public IndexSum maxRow() {
if (_mat.length == 0) return null;
return maxRow(new IndexSum(0, SumRow(0)));
}
private IndexSum maxRow(IndexSum thisRow) {
if (thisRow.index == _mat.length - 1) return thisRow; //end case - last row
IndexSum nextRow = maxRow(new IndexSum(thisRow.index + 1 , SumRow(thisRow.index + 1)));
return thisRow.sum > nextRow.sum ? thisRow : nextRow;
}
Are member fields accepted ?
int index = -1;
private int maxRow(int i) {
if (i == _mat.length - 1) {
index = i;
return SumRow(i); // end case - last row
}
int max = maxRow(i + 1);
int thisRow = SumRow(i);
if (thisRow > max) {
index = i;
}
if (i == 0) {
return index;
}
return thisRow > max ? thisRow : max;
}
I'm trying to implement recursive Knapsack I used the common algorithm to write it as following:
int pack(int n, int s) {
if (n < 0)
return 0;
if (List[n].s > s)
return pack(n-1, s);
else {
int max = Math.max(pack(n-1,s), pack(n-1, s -List[n].s) + List[n].v);
return max;
}
}
Is there anyway I can know which items were packed?
Update: I want only the items that belong to best choice and I don't want to change the function header.
EDIT Using array to track items, what's wrong with this?
int pack(int n , int s)
{
if(n < 0)
{
counter =0;
return 0;
}
if (itemsList[n].s > s)
{
return pack(n-1, s);
}
else
{
int max1 = pack(n-1,s);
int max2 = pack(n-1, s - itemsList[n].s) + itemsList[n].v ;
if(max2 > max1)
{
flag1[counter] = new item();
flag1[counter] = itemsList[n];
counter ++;
}
return max(max1, max2);
}
}
Something like this ?
int pack(int n, int s) {
if (n < 0)
return 0;
if (List[n].s > s)
return pack(n-1, s);
else {
int without = pack(n-1,s);
int with = pack(n-1, s-List[n].s) + List[n].v;
if (with >= without) {
System.out.println(n);
}
return Math.max(with, without);
}
}
or, you can return the list of results:
int pack(int n, int s) {
return reallyPack(n, s, new ArrayList<Item>());
}
int reallyPack(int n, int s, List<Item> l) {
if (n < 0)
return 0;
if (List[n].s > s)
return reallyPack(n-1, s);
else {
int without = reallyPack(n-1,s);
int with = reallyPack(n-1, s-List[n].s) + List[n].v;
if (with >= without) {
l.add(itemsList[n]);
}
return Math.max(with, without);
}
}
and of course, you still know how many items were selected: this is simply the size of the returned list.
You can keep track of all items that are currently selected (using e.g. boolean[] field). Then you have to remember the max in the calls of pack with n < 0.
int maximum;
int currentMax;
boolean[] packed;
boolean[] maxPacked;
int pack(int n, int s) {
if (n < 0) {
if (maximum < currentMax) {
// found better selection
maximum = currentMax;
// copy array
for (int i = 0; i < packed.length; i++)
maxPacked[i] = packed[i];
}
return 0;
}
packed[n] = false;
int maxWithout = pack(n-1, s);
if (List[n].s > s) {
return maxWithout;
} else {
packed[n] = true;
currentMax += List[n].v;
int maxWith = pack(n-1, s -List[n].s) + List[n].v;
currentMax -= List[n].v;
return Math.max(maxWith, maxWithout);
}
}
void callingFunction() {
int maxCost = //...;
// always possible to choose no items
maximum = 0;
currentMax = 0;
packed = new boolean[List.length];
maxPacked = new boolean[List.length];
pack(List.length-1, maxCost);
// print best selection
System.out.println(Arrays.toString(maxPacked));
}
Can I get some help please? I have tried many methods to get this to work i got the array sorted and to print but after that my binary search function doesnt want to run and give me right results. It always gives me -1. Any help?
public class BinarySearch {
public static final int NOT_FOUND = -1;
public static int binarySearch(double[] a, double key) {
int low = 0;
int high = a.length -1;
int mid;
while (low<=high) {
mid = (low+high) /2;
if (mid > key)
high = mid -1;
else if (mid < key)
low = mid +1;
else
return mid;
}
return NOT_FOUND;
}
public static void main(String[] args) {
double key = 10.5, index;
double a[] ={10,5,4,10.5,30.5};
int i;
int l = a.length;
int j;
System.out.println("The array currently looks like");
for (i=0; i<a.length; i++)
System.out.println(a[i]);
System.out.println("The array after sorting looks like");
for (j=1; j < l; j++) {
for (i=0; i < l-j; i++) {
if (a[i] > a[i+1]) {
double temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
}
for (i=0;i < l;i++) {
System.out.println(a[i]);
}
System.out.println("Found " + key + " at " + binarySearch(double a[], key));
}
}
you are not actually comparing with the array values. in
while (low <= high) {
mid = (low + high) / 2;
if (mid > key) {
high = mid - 1;
} else if (mid < key) {
low = mid + 1;
} else {
return mid;
}
}
Instead use this section
while (low <= high) {
mid = (low + high) / 2;
if (a[mid] > key) {
high = mid - 1;
} else if (a[mid] < key) {
low = mid + 1;
} else {
return mid;
}
}
You were correct to find the indexes, but what you were doing is that you were just comparing index number with your key, which is obviously incorrect. When you write a[mid] you will actually compare your key with the number which is at index mid.
Also the last line of code is giving compile error, it should be
System.out.println("Found " + key + " at " + binarySearch(a, key));
Here
if (mid > key)
high = mid -1;
else if (mid < key)
low = mid +1;
else
return mid;
You're comparing index to a value (key) in array. You should instead compare it to a[mid]
And,
System.out.println("Found " + key + " at " + binarySearch(double a[], key));
Should be
System.out.println("Found " + key + " at " + binarySearch(a, key));
public static double binarySearch(double[] a, double key) {
if (a.length == 0) {
return -1;
}
int low = 0;
int high = a.length-1;
while(low <= high) {
int middle = (low+high) /2;
if (b> a[middle]){
low = middle +1;
} else if (b< a[middle]){
high = middle -1;
} else { // The element has been found
return a[middle];
}
}
return -1;
}
int binarySearch(int list[], int lowIndex, int highIndex, int find)
{
if (highIndex>=lowIndex)
{
int mid = lowIndex + (highIndex - lowIndex)/2;
// If the element is present at the
// middle itself
if (list[mid] == find)
return mid;
// If element is smaller than mid, then
// it can only be present in left subarray
if (list[mid] > find)
return binarySearch(list, lowIndex, mid-1, find);
// Else the element can only be present
// in right subarray
return binarySearch(list, mid+1, highIndex, find);
}
// We reach here when element is not present
// in array
return -1;
}
I somehow find the iterative version not quite easy to read, recursion makes it nice and easy :-)
public class BinarySearch {
private static int binarySearchMain(int key, int[] arr, int start, int end) {
int middle = (end-start+1)/2 + start; //get index of the middle element of a particular array portion
if (arr[middle] == key) {
return middle;
}
if (key < arr[middle] && middle > 0) {
return binarySearchMain(key, arr, start, middle-1); //recurse lower half
}
if (key > arr[middle] && middle < arr.length-1) {
return binarySearchMain(key, arr, middle+1, end); //recurse higher half
}
return Integer.MAX_VALUE;
}
public static int binarySearch(int key, int[] arr) { //entry point here
return binarySearchMain(key, arr, 0, arr.length-1);
}
}
Here is a solution without heap. The same thing can be done in an array.
If we need to find 'k' largest numbers, we take an array of size 'k' populated with first k items from the main data source. Now, keep on reading an item, and place it in the result array, if it has a place.
public static void largestkNumbers() {
int k = 4; // find 4 largest numbers
int[] arr = {4,90,7,10,-5,34,98,1,2};
int[] result = new int[k];
//initial formation of elems
for (int i = 0; i < k; ++i) {
result[i] = arr[i];
}
Arrays.sort(result);
for ( int i = k; i < arr.length; ++i ) {
int index = binarySearch(result, arr[i]);
if (index > 0) {
// insert arr[i] at result[index] and remove result[0]
insertInBetweenArray(result, index, arr[i]);
}
}
}
public static void insertInBetweenArray(int[] arr, int index, int num) {
// insert num at arr[index] and remove arr[0]
for ( int i = 0 ; i < index; ++i ) {
arr[i] = arr[i+1];
}
arr[index-1] = num;
}
public static int binarySearch(int[] arr, int num) {
int lo = 0;
int hi = arr.length - 1;
int mid = -1;
while( lo <= hi ) {
mid = (lo+hi)/2;
if ( arr[mid] > num ) {
hi = mid-1;
} else if ( arr[mid] < num ) {
lo = mid+1;
} else {
return mid;
}
}
return mid;
}
int BinSearch(int[] array, int size, int value)
{
if(size == 0) return -1;
if(array[size-1] == value) return size-1;
if(array[0] == value) return 0;
if(size % 2 == 0) {
if(array[size-1] == value) return size-1;
BinSearch(array,size-1,value);
}
else
{
if(array[size/2] == value) return (size/2);
else if(array[size/2] > value) return BinSearch(array, (size/2)+1, value);
else if(array[size/2] < value) return (size/2)+BinSearch(array+size/2, size/2, value);
}
}
or
Binary Search in Array
/**
* Find whether 67 is a prime no
* Domain consists 25 of prime numbers
* Binary Search
*/
int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
int min = 0,
mid,
max = primes.length,
key = 67,
count= 0;
boolean isFound = false;
while (!isFound) {
if (count < 6) {
mid = (min + max) / 2;
if (primes[mid] == key) {
isFound = true;
System.out.println("Found prime at: " + mid);
} else if (primes[mid] < key) {
min = mid + 1;
isFound = false;
} else if (primes[mid] > key) {
max = mid - 1;
isFound = false;
}
count++;
} else {
System.out.println("No such number");
isFound = true;
}
}
/**
HOPE YOU LIKE IT
A.K.A Binary Search
Take number array of 10 elements, input a number a check whether the number
is present:
**/
package array;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
class BinaryS
{
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter a number: ");
int n=Integer.parseInt(br.readLine());
int a[]={10,20,30,40,50,60,70,80,90,100};
int upper=a.length-1,lower=0,mid;
boolean found=false;
int pos=0;
while(lower<=upper)
{
mid=(upper+lower)/2;
if(n<a[mid])upper=mid-1;
else if(n>a[mid])lower=mid+1;
else
{
found=true;
pos=mid;
break;
}
}
if(found)System.out.println(n+" found at index "+pos);
else System.out.println(n+" not found in array");
}
}
Well I know I am posting this answer much later.
But according to me its always better to check boundary condition at first.
That will make your algorithm more efficient.
public static int binarySearch(int[] array, int element){
if(array == null || array.length == 0){ // validate array
return -1;
}else if(element<array[0] || element > array[array.length-1]){ // validate value our of range that to be search
return -1;
}else if(element == array[0]){ // if element present at very first element of array
return 0;
}else if(element == array[array.length-1]){ // if element present at very last element of array
return array.length-1;
}
int start = 0;
int end = array.length-1;
while (start<=end){
int midIndex = start + ((end-start)/2); // calculate midIndex
if(element < array[midIndex]){ // focus on left side of midIndex
end = midIndex-1;
}else if(element > array[midIndex]){// focus on right side of midIndex
start = midIndex+1;
}else {
return midIndex; // You are in luck :)
}
}
return -1; // better luck next time :(
}
static int binarySearchAlgorithm() {
// Array should be in sorted order. Mandatory requirement
int[] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int lowIndex = 0;
int valueToFind = 8;
int highIndex = a.length - 1;
while (lowIndex <= highIndex) {
//Finding the midIndex;
int midIndex = (highIndex + lowIndex) / 2;
// Checking if midIndex value of array contains the value to be find.
if (a[midIndex] == valueToFind) {
return midIndex;
}
// Checking the mid Index value is less than the value to be find.
else if (a[midIndex] < valueToFind) {
// If Yes, changing the lowIndex value to midIndex value + 1;
lowIndex = midIndex + 1;
} else if (a[midIndex] > valueToFind) {
// If Yes, changing the highIndex value to midIndex value - 1;
highIndex = midIndex - 1;
} else {
return -1;
}
}
return -1;
}