the Infinite array
is a special type of array where its size or end is unknown.
it can be considered as a stream
of elements whose size keeps increasing, for example, comments or likes on a social media post. For the sake of this question, a finite size array will be used but to keep it as an infinite array
, the array.length
function will not be used to find the end of the array.
If need to find a target element in a sorted array, find the pattern and think of a Binary Search first.
binary search requires the start and end of the array, but since the array is infinite, the end cannot be calculated. so take the first element, apply binary search and increase the size of the array exponentially ie double the current size
package org.wesome.dsalgo;
public class BinarySearchInInfiniteArray {
public static int binarySearchInInfiniteArray(int[] arr, int find) {
int start = 0, end = arr.length - 1;
while (find > arr[end]) {
// target element is less than the end element, so for the next chunk, the end element doesn't need to check again so that the new start will be from the next of the previous end
int newStart = end + 1;
int sizeOfChunk = end - start + 1;
// new end will be the previous end which was the size of the array, plus the size of chunk * 2
end = end + sizeOfChunk + 1;
start = newStart;
}
return binarySearch(arr, find);
}
public static int binarySearch(int[] arr, int find) {
int start = 0, end = arr.length - 1;
while (start <= end) {
int mid = start + (end - start) / 2;
// If the element is present in the middle itself
if (arr[mid] == find) {
return mid;
}
// If the element is smaller than mid, then it can only be present in left sub-array
else if (arr[mid] > find) {
end = mid - 1;
}
// Else the element can only be present in right sub-array
else {
start = mid + 1;
}
}
return -1;
}
}
package org.wesome.dsalgo;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.wesome.dsalgo.BinarySearchInInfiniteArray.binarySearchInInfiniteArray;
public class BinarySearchInInfiniteArrayTest {
@Test
void binarySearchInInfiniteArrayTest1() {
int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int binarySearch = binarySearchInInfiniteArray(arr, 10);
Assertions.assertEquals(9, binarySearch);
}
@Test
void binarySearchInInfiniteArrayTest2() {
int[] arr = new int[]{10, 11, 12, 13, 14, 15};
int binarySearch = binarySearchInInfiniteArray(arr, 10);
Assertions.assertEquals(0, binarySearch);
}
@Test
void binarySearchInInfiniteArrayTest3() {
int[] arr = new int[]{90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100};
int binarySearch = binarySearchInInfiniteArray(arr, 99);
Assertions.assertEquals(9, binarySearch);
}
}
plugins {
id 'java'
id "io.freefair.lombok" version "6.2.0"
}
group = 'org.wesome'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = JavaVersion.VERSION_1_8
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.6.2'
}
test {
useJUnitPlatform()
}
in normal binary search top-down
approach is taken, ie a finite array is divided into N subarrays to reach 1 target index in O(log n)
. but in this question, the algorithm will go in reverse, so a bottom-up
approach will be taken, ie from 1 target index. increase to an array, so the time complexity will still remain O(log n)
.