Given an array, data[ ], my goal is to find the number of elements followed by a double.
(If it was a simple for loop, it'd look something like this)
for(int i = 0; i < data.length - 1; i ++) {
if(data[i]*2 == data[i+1]) {
count++;
}
}
My issue, however, is finding a certain section of the code recursively, as noted by the question marks. I'm having trouble determining how to compare a value found in the previous method call to the current method call.
public int allDoubles(int[] data) {
int count = 0;
//return the total doubles found
return doubleFinder(data, 0, data.length, count);
}
private int doubleFinder(int data[], int low, int high, int count) {
if (low == high) {
return 0;
} else { // low < high
if( ?(previous value == current value)? ) {
count++;
}
doubleFinder(data, low, high -1, count);
}
return count;
}
You are not passing the calculated result back up to the calling method. Since java is call-by-value, this won't work. Also you pass the wrong values to doubleFinder in allDoubles: You should use (data, 0, data.length-1, count) instead of (data, 0, data.length, count).
Your method could be fixed like this:
private int doubleFinder(int data[], int low, int high, int count) {
if (low == high) {
return count;
} else { // low < high
if(data[high-1]*2 == data[high]) {
count++;
}
// pass the count from the base case to calling method
return doubleFinder(data, low, high -1, count);
}
}
but you can even remove count:
private int doubleFinder(int data[], int low, int high) {
if (low == high) {
// just 1 value
return 0;
} else if (data[low]*2 == data[low+1]) {
// 1 "double" found -> add 1
return 1 + doubleFinder(data, low+1, high);
} else {
return doubleFinder(data, low+1, high);
}
}
Here is an implementation of doubleFinder() which recursively compares data[i] == 2*data[i-i], beginning with the highest index in the input array data. It counts 1 for every double (not the type) found, and returns the total count of doubles for the input entered.
private int doubleFinder(int data[], int index) {
if (index <= 0) {
return 0; // reached last number in array 'data'
} else {
if (data[index] == 2*data[index-1])
return doubleFinder(data, index-1) + 1;
else {
doubleFinder(data, index-1)
}
}
}
Related
The objective is to return the index of an element in a string array if present. The method uses a basic binary search using compareTo statements. With more than two elements in a tested array, the method will not detect the present element and return -1. The Java code this question is referring to is below. How do I make the binary search method work as intended?
public static int binarySearch(String[] array, String x) {
int high = array.length - 1;
int low = 0;
while (low <= high) {
int mid = low + (high - low) / 2;
if (x.compareTo(array[mid]) == 0) {
return mid;
}
if (x.compareTo(array[mid]) > 0) {
low = mid + 1;
}
else {
high = mid - 1;
}
}
return -1;
}
add an extra variable and set it to -1;
int loc=-1;
change the code
int mid=low+(high-low)/2;
to
int mid=(low+high)/2;
if(x.compareTo(array[mid]==0)
{
loc=mid;
break;
}
else if(x<array[mid])
{
last=mid-1;
}
else
{
low=mid+1;
}
then
if(loc>=0)
{
System.out.println(loc+1);
}
else
{
System.out.println("no element");
}
Homework Question! We are using Binary Searches with Generic Arrays and Comparator. The assignment requires we have Integer / Double / String type arrays and that we can search each of them with a Binary Search. I have successfully used Binary Searching on non-Generic arrays before, this is a bit more difficult though. I generate my Arrays prior to calling the search, prompt user for selection, then perform the search (that's the idea). The currently implement Binary Search SORT of works. It will find the key on the first two index locations...throw a stackoverflow exception on mid range index, high end index return nothing, and input not found spits out -1 (I will add an output for that when the Binary Search works). I know the problem is falling in how I am implementing my Binary Search, I am just failing to fix it. Any help would be appreciated. Code is below:
public static void searchIntegers() {
System.out.print("Please enter the Integer you would like to search for: ");
try {
keyInt = input.nextInt();
System.out.print(keyInt + " is found in index " + binarySearch(integerArray, keyInt));
}
catch (InputMismatchException inputMismatchException) {
input.nextLine();
System.out.printf("Please enter only Integers. Try again. \n\n");
}
}
public static <E extends Comparable<E>> int binarySearch(E[] list, E key) {
return binarySearch(list, key, 0, list.length);
}
public static <E extends Comparable<E>> int binarySearch(E[] list, E key, int low, int high) {
int mid = low + high / 2;
if (low > high) {
return -1;
}
else if (list[mid].equals(key)) {
return mid;
}
else if (list[mid].compareTo(key) == -1) {
return binarySearch(list, key, mid +1, high);
}
else {
return binarySearch(list, key, low, mid -1);
}
}
public static void generateArrays() {
//GENERATE INTEGER ARRAY
for(i = 0; i < 10; i++) {
integerArray[i] = generator.nextInt(100);
}
Arrays.sort(integerArray);
//GENERATE DOUBLE ARRAY
for(i = 0; i < 10; i ++) {
doubleArray[i] = i + generator.nextDouble();
}
Arrays.sort(doubleArray);
}
It's basically failing at the check for low and high and going into an loop
Try this -
public static <E extends Comparable<E>> int binarySearch(E[] list, E key, int low, int high) {
int mid = (low + high) / 2;
if (low > high) {
return -1;
}
if (list[mid].equals(key)) {
return mid;
} else if (list[mid].compareTo(key) == -1) {
return binarySearch(list, key, mid + 1, high);
} else {
return binarySearch(list, key, low, mid - 1);
}
}
You need to add brackets to your mid calculation.
Just a suggestion, check for overflow conditions as well.
I need to get the count of numbers less than the first integer in an array using recursion. I am given a function definition as
public static int countGreaterThanFirst(int[]
numbers, int startIndex, int endIndex, int firstNumber){}
I am not supposed to use a loop or global/static variable. How can I convert my implementation below to satisfy the two conditions above. I have recently asked another similar question but this is a bit different due to the need to keep track of the count variable. If someone can help, I will really appreciate.
Below is my implementation with a loop.
public static int countGreaterThanFirst(int[] numbers, int startIndex, int endIndex, int firstNumber) {
int greater_than_first = 0;
for (int count = startIndex; count <= endIndex; count++) {
if (numbers[count] > firstNumber) {
greater_than_first++;
}
}
return greater_than_first;
}
Probably you don't need that much parameters:
public static int countGreaterThanFirst(int[] numbers, int currentIndex) {
if (currentIndex == numbers.length) return 0;
else {
if (numbers[currentIndex] > numbers[0]) {
return 1 + countGreaterThanFirst(numbers, currentIndex + 1);
} else {
return countGreaterThanFirst(numbers, currentIndex + 1);
}
}
}
and you should invoke it with (for example):
countGreaterThanFirst(someArray, 1);
If you meant to find "all the numbers between numbers[startIndex] and numbers[endIndex] that are greater than firstNumber, then the implementation should be pretty similar to the above one:
public static int countGreaterThanFirst(int[] numbers, int startIndex, int endIndex, int firstNumber) {
if (startIndex > endIndex) return 0;
else {
if (numbers[startIndex] > firstNumber) {
return 1 + countGreaterThanFirst(numbers, startIndex + 1, endIndex, firstNumber);
} else {
return countGreaterThanFirst(numbers, startIndex + 1, endIndex, firstNumber);
}
}
}
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;
}
I need an algorithm to determine if an array contains two elements that sum to a given integer.
The array is sorted.
The algorithm should be recursive and runs in O(n).
The recursive step should be based on the sum, meaning the method passes the sum and return true or false depending on the end result (if two elements are found - return true, else - return false)
Only linear data structures can be used.
Any ideas are appreciated..
You can convert any iterative algorithm into a recursive one by using (for instance) tail recursion. I'd be more expansive, if it weren't homework. I think you'll understand it from the other post.
Normally I'd use a Map, but since one of the requirements is to use a linear data structure, I think that's excluded, so I'd go about using a boolean array.
public boolean hasSum( int[] numbers, int target )
{
boolean[] hits = new boolean[ target + 1 ];
return hasSumRecursive( 0, numbers, target, hits );
}
public boolean hasSumRecursive( int index, int[] numbers, int target, boolean[] hits )
{
...
}
Hopefully this is a good enough hint.
I think hash is ok, for example, 1,3,7,9,12,14,33...
if we want sum=21, we hash the numbers into a hash table, So, O(n).
we iterator them, when we get 7, we let 21-7=14, so we hash 14, we can find it. so 7+14=21,
we got it!
Here is a solution witch takes into account duplicate entries. It is written in javascript and assumes array is sorted. The solution runs in O(n) time and does not use any extra memory aside from variable.
var count_pairs = function(_arr,x) {
if(!x) x = 0;
var pairs = 0;
var i = 0;
var k = _arr.length-1;
if((k+1)<2) return pairs;
var halfX = x/2;
while(i<k) {
var curK = _arr[k];
var curI = _arr[i];
var pairsThisLoop = 0;
if(curK+curI==x) {
// if midpoint and equal find combinations
if(curK==curI) {
var comb = 1;
while(--k>=i) pairs+=(comb++);
break;
}
// count pair and k duplicates
pairsThisLoop++;
while(_arr[--k]==curK) pairsThisLoop++;
// add k side pairs to running total for every i side pair found
pairs+=pairsThisLoop;
while(_arr[++i]==curI) pairs+=pairsThisLoop;
} else {
// if we are at a mid point
if(curK==curI) break;
var distK = Math.abs(halfX-curK);
var distI = Math.abs(halfX-curI);
if(distI > distK) while(_arr[++i]==curI);
else while(_arr[--k]==curK);
}
}
return pairs;
}
I solved this during an interview for a large corporation. They took it but not me.
So here it is for everyone.
Start at both side of the array and slowly work your way inwards making sure to count duplicates if they exist.
It only counts pairs but can be reworked to
use recursion
find the pairs
find pairs < x
find pairs > x
Enjoy!
It is pretty easy. It is important for array to be sorted.
Correct algorithm with O(n) time complexity and no additional space is:
public static boolean isContainsSum(int[] arr, int sum) {
for (int i = 0, j = arr.length - 1; i < j; ) {
if (arr[i] + arr[j] == sum)
return true;
if (arr[i] + arr[j] < sum)
i++;
else
j--;
}
return false;
}
To make it recursive, you need just replace i and j iterations with recursive call:
public static boolean isContainsSumRecursive(int[] arr, int sum) {
return isContainsSumRecursive(arr, sum, 0, arr.length - 1);
}
private static boolean isContainsSumRecursive(int[] arr, int sum, int i, int j) {
if (i == j)
return false;
if (arr[i] + arr[j] == sum)
return true;
if (arr[i] + arr[j] < sum)
return isContainsSumRecursive(arr, sum, i + 1, j);
return isContainsSumRecursive(arr, sum, i, j - 1);
}
Here is my solution: I iterate until the first number is greater than the expected sum, then until to second one or the sum of two is greater than the expected sum. If I do not want a correct answer, I return {-1,-1} (assuming all numbers are positive integers)
{
private static int[] sumOfTwo(int[] input, int k) {
for (int i = 0; i < input.length - 1; i++) {
int first = input[i];
for (int j = 1; j < input.length; j++) {
int second = input[j];
int sum = first + second;
if (sum == k) {
int[] result = {first, second};
return result;
}
if (second > k || sum > k) {
break;
}
}
if (first > k) {
break;
}
}
int[] begin = {-1, -1};
return begin;
}
}
Here is the recursion method to perform the groupSum
public boolean groupSum(int start, int[] nums, int target)
{
if (start >= nums.length) {
return (target == 0);
}
return groupSum(start + 1, nums, target - nums[start]) || groupSum(start +
1,nums,target)
}
def ExistsSum(A, i, j, Target):
if i >= j:
return False # Failure, all candidate pairs exhausted
if A[i] + A[j] < Target:
return ExistsSum(A, i+1, j, Target) # Try a larger sum
if A[i] + A[j] > Target:
return ExistsSum(A, i, j-1, Target) # Try a smaller sum
return True # Success
Run with
ExistsSum(A, 0, len(A)-1, Target)
bool solve(vector<int> &sorted_array, int l, int r, int target) {
if(l>=r) {
return false;
}
if(sorted_array[l] + sorted_array[r] == target) {
return true;
}
if(sorted_array[l] + sorted_array[r] > target) {
return solve(sorted_array, l, r-1, target);
}
if(sorted_array[l] + sorted_array[r] < target) {
return solve(sorted_array, l+1, r, target);
}
}
int main() {
vector<int> a = ...
solve(a, 0, a.size() - 1, target)
}
Here is my solution using recursion
pair<int,int> twoSum(int arr[], int s, int e, int target, pair<int, int>p){
//base case
if(arr[s] + arr[e] == target){
// pair<int,int>p;
p.first = arr[s];
p.second = arr[e];
return p;
}
while(s < e-1){
if(arr[s] + arr[e] < target){
s++;
return twoSum(arr, s, e, target, p);
}
if(arr[s] + arr[e] > target){
e--;
return twoSum(arr, s, e, target, p);
}
}
//if there is no pair possible
cout<<"pair is not possible" <<endl;
return p;
}
Sort the array. Search for the complement of each number (sum-number). Complexity O(nlogn).