Search an element in sorted 2d matrix - java

package kunal;
import java.util.Arrays;
public class SortedMatrix {
public static void main(String[] args) {
int[][] matrix = {
{20, 30, 40, 45},
{50, 55, 60, 65, 66, 67},
{70, 71, 72, 73},
{74, 75, 78, 80}
};
int target = 67;
System.out.println(Arrays.toString(search(matrix, target)));
}
static int[] search(int[][] matrix, int target) {
// return the index of floor number
int floorIndex = floor(matrix, target);
int binarySearch = binarySearch(matrix, target, floorIndex);
if(binarySearch != -1) {
return new int[] {floorIndex, binarySearch};
}
return new int[] {-1, -1};
}
static int floor(int[][] matrix, int target) {
int start = 0;
int end = matrix.length - 1;
int colFix = 0;
while(start <= end) {
int mid = start + (end - start)/2;
if(target == matrix[mid][colFix]) {
return mid;
}
if(target > matrix[mid][colFix]) {
start = mid + 1;
}else {
end = mid - 1;
}
}
return end;
}
static int binarySearch(int[][] matrix, int target, int floorIndex) {
int start = 0;
int end = matrix[floorIndex].length - 1;
int rowFix = floorIndex;
while(start <= end) {
int mid = start + (end - start)/2;
if(target == matrix[rowFix][mid]) {
return mid;
}
if(target > matrix[rowFix][mid]) {
start = mid + 1;
}else {
end = mid - 1;
}
}
return -1;
}
}
In this code first I find the floor(largest number smaller than or equal to the traget) in the first column. after that applying the binary search in the row where i found floor.
this code works on eclispe editor. And successfully run on leetcode too but when i try to submit it shows runtime error. "index -1 out of bond for length 1". please correct the code

Related

Jump search with Strings

i have been doing research on the jump search algorithm in an array. But i am confused on how you can use the search method with strings. Can anyone give me a link on where to look, or an example on here? Every example i have seen has been with numbers
public class JumpSearch
{
public static int jumpSearch(int[] arr, int x)
{
int n = arr.length;
int step = (int)Math.floor(Math.sqrt(n));
int prev = 0;
while (arr[Math.min(step, n)-1] < x)
{
prev = step;
step += (int)Math.floor(Math.sqrt(n));
if (prev >= n)
return -1;
}
while (arr[prev] < x)
{
prev++;
if (prev == Math.min(step, n))
return -1;
}
if (arr[prev] == x)
return prev;
return -1;
}
public static void main(String [ ] args)
{
int arr[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21,
34, 55, 89, 144, 233, 377, 610};
int x = 55;
// Find the index of 'x' using Jump Search
int index = jumpSearch(arr, x);
System.out.println("\nNumber " + x +
" is at index " + index);
}
}

Target element is given and find the ceiling of that element

What I tried
here I've used order agnostic binary search
I've tried creating a method called webs inside which I declared a boolean variable to check whether the array is sorted in ascending or descending order(considering that order in unknown) and further I used an if condition for the same.
//find the ceiling of a number
//ceiling of a given number is the smallest element
//in the array greater than or equal to target element
public class webs{
public static void main(String[] args){
int arr[] = {-18, -12, -4, 0, 2, 3, 4, 15, 16, 18, 22, 45, 89};
int target = 45;
int sol = ceiling(arr, target);
System.out.println(sol);
}
static int ceiling(int arr[], int target){
int ans = Integer.MIN_VALUE;
int start = 0;
int end = arr.length-1;
while(start <= end){
int mid = start + (end - start)/2;
boolean isAsc = arr[start] < arr[end];
if(isAsc){
if(arr[mid] < target){
start = mid + 1;
} else{
end = mid - 1;
}
}else{
if(arr[mid] > target){
start = mid + 1;
}else{
end = mid - 1;
}
}
for(int nums: arr){
if(nums > target){
if(nums > ans){
ans = nums;
}
}
}
return ans;
}
return start;
}
}
I want it to return ceiling of the target element
Output
it is returning the greatest number present in the array
What you can do is simply perform a normal binary search. If the target is found at index i, then the ceiling is at i. If the target is not found, then the ceiling is the index where it stops.
static int ceiling(int[] arr, int target){
int low = 0, high = arr.length-1;
while(true){
int mid = (low+high)/2;
if (low >= high) return arr[low];
if (arr[mid] == target) return arr[mid];
else if (target > arr[mid]) low = mid+1;
else if (target < arr[mid]) high = mid-1;
}
}
public static void main(String[] args){
int arr[] = {-18, -12, -4, 0, 2, 3, 4, 15, 16, 18, 22, 45, 89, 100};
int target = 31;
int sol = ceiling(arr, target);
System.out.println(sol);
}

Recursion Order of Operations

I am having some trouble understanding this recursion code:
class Main {
public static void main(String[] args) {
int[] intArray = { 20, 35, -15, 7, 55, 1, -22 };
mergeSort(intArray, 0, intArray.length);
for (int i = 0; i < intArray.length; i++) {
System.out.println(intArray[i]);
}
}
// { 20, 35, -15, 7, 55, 1, -22 }
public static void mergeSort(int[] input, int start, int end) {
if (end - start < 2) {
return;
}
int mid = (start + end) / 2;
mergeSort(input, start, mid);
mergeSort(input, mid, end);
merge(input, start, mid, end);
}
// { 20, 35, -15, 7, 55, 1, -22 }
public static void merge(int[] input, int start, int mid, int end) {
if (input[mid - 1] <= input[mid]) {
return;
}
int i = start;
int j = mid;
int tempIndex = 0;
int[] temp = new int[end - start];
while (i < mid && j < end) {
temp[tempIndex++] = input[i] <= input[j] ? input[i++] : input[j++];
}
System.arraycopy(input, i, input, start + tempIndex, mid - i);
System.arraycopy(temp, 0, input, start, tempIndex);
}
}
Can someone help me identify the operation order in the code? When we call mergeSort, are we synchronously finishing the function or are we moving on to the next step and coming back to it later?

Quick Sort not sorting iterative solution

I currently have the below code for my quick sort. As you can see it is not producing the correct output. Any help will be greatly appreciated. I need the pivot to be the first item in the array. As you can also see i am measuring the time it takes to run, but please ignore that for the time being.
edit: to be specific it works correctly when i have a list in descending order and ascending order(already sorted), but when i try a random list it does not work.
Output:
QuickSort:
Quick Sort Took 181023 nanoseconds
Quick Sort Took 0 milliseconds
Sorted Quick Sort: 25, 12, 17, 13, 20, 7, 5, 16, 11, 26, 24, 18, 9, 4, 21, 1, 23, 27, 15, 19, 28, 14, 8, 22, 6, 3, 2, 10, 29, 40, 37, 32, 44, 38, 35, 41, 39, 31, 42, 30, 43, 36, 34, 33, 45, 46, 47, 48, 49, 50,
Code:
class QuickSort {
public static int Partition(int[] numbers, int left, int right){
//selects the first item at position [0] as the pivot
//left is given 0 when the method is called
int pivot = numbers[left];
while (true)
{
while (numbers[left] < pivot)
left++;
while (numbers[right] > pivot)
right--;
if (left < right)
{
int temp = numbers[right];
numbers[right] = numbers[left];
numbers[left] = temp;
}
else
{
return right;
}
}
}
//method to check for special cases
public static void QuickSort_Check(int[] numbers, int left, int right)
{
//special case of 2 items to be sorted
if(right == 1){
if(numbers[0] >= numbers[1]){
System.out.print("This is a special case of 2 inputs: ");
System.out.print(numbers[1] + ", " + numbers[0]);
System.exit(0);
}
else {
System.out.print("This is a special case of 2 inputs: ");
System.out.print(numbers[0] + ", " + numbers[1]);
System.exit(0);
}
System.exit(0);
}
//special case of 1 item to be sorted
else if (right == 0){
System.out.print("This is a special case of 1 input: ");
System.out.print(numbers[0]);
System.exit(0);
}
else {
QuickSort_Iterative(numbers, left, right);
}
}
public static class QuickPosInfo
{
public int left;
public int right;
};
public static QuickPosInfo spot = new QuickPosInfo();
public static void QuickSort_Iterative(int[] numbers, int left, int right)
{
if(left >= right)
return; // Invalid index range
LinkedList<QuickPosInfo> list = new LinkedList< QuickPosInfo>();
spot.left = left;
spot.right = right;
list.add(spot);
while(true)
{
if(list.size() == 0)
break;
left = list.get(0).left;
right = list.get(0).right;
list.remove(0);
int pivot = Partition(numbers, left, right);
if(pivot > 1)
{
spot.left = left;
spot.right = pivot - 1;
list.add(spot);
}
if(pivot + 1 < right)
{
spot.left = pivot + 1;
spot.right = right;
list.add(spot);
}
}
}
}
This partition method correctly sorted half the array, then did not sort the other half so I believe the problem is in your QuickSort_Iterative(); when the pivot equals 21 it just infinitely swaps 20 and 21.
private static int partition(int[] arr,int left,int right) {
int pivot = arr[right];
int small = left-1;
for(int k = left;k < right;k++)
{
if(arr[right] <= pivot)
{
small++;
swap(arr,right,small);
}
}
swap(arr,right,small+1);
System.out.println("Pivot= "+arr[small+1]);//prints out every sort
System.out.println(Arrays.toString(arr));
return small+1;
}
private static void swap(int[] arr, int k, int small) {//easy swap method
int temp;
temp = arr[k];
arr[k] = arr[small];
arr[small] = temp;
}
UPDATE
Here is the requested method. I believe that the problem with your original one is that you are not modifying that values of left and right properly as the array is sorted.
void QuickSort(int arr[], int left, int right)
{
// create auxiliary stack
int stack[] = new int[right-l+1];
// initialize top of stack
int top = -1;
// push initial values in the stack
stack[++top] = left;
stack[++top] = right;
// keep popping elements until stack is not empty
while (top >= 0)
{
// pop right and l
right = stack[top--];
left = stack[top--];
// set pivot element at it's proper position
int p = partition(arr, left, right);
// If there are elements on left side of pivot,
// then push left side to stack
if ( p-1 > left )
{
stack[ ++top ] = l;
stack[ ++top ] = p - 1;
}
// If there are elements on right side of pivot,
// then push right side to stack
if ( p+1 < right )
{
stack[ ++top ] = p + 1;
stack[ ++top ] = right;
}
}
}
I don't know that will help you out or not you can also try the below code for same.
public class Demo {
private int array[];
private int length;
public void sort(int[] inputArr) {
if (inputArr == null || inputArr.length == 0) {
return;
}
this.array = inputArr;
length = inputArr.length;
quickSort(0, length - 1);
}
private void quickSort(int lowerIndex, int higherIndex) {
int i = lowerIndex;
int j = higherIndex;
int pivot = array[lowerIndex+(higherIndex-lowerIndex)/2];
while (i <= j) {
while (array[i] < pivot) {
i++;
}
while (array[j] > pivot) {
j--;
}
if (i <= j) {
exchangeNumbers(i, j);
i++;
j--;
}
}
if (lowerIndex < j)
quickSort(lowerIndex, j);
if (i < higherIndex)
quickSort(i, higherIndex);
}
private void exchangeNumbers(int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public static void main(String a[]){
Demo sorter = new Demo();
int[] input = {8,693,29,3,2,8,29,82,4,26,2,62,82,6,52,9,42,6,52,66,2,8};
sorter.sort(input);
for(int i:input){
System.out.print(i);
System.out.print(" ");
}
}
}

Searching a sorted list with two different algorithms to find if there exists an index i such that X[i]=i

Note that the list will never contain duplicates.
The list is loaded from a text file and is the following 1,2,3,4,5,6,7,8,9.
My first choice since the list is sorted was a linear search and worked fine. Then I tried to use binary search but it does not work correctly.
Here is the code:
public boolean binarySearch() {
int i=0;
int size = list.size() - 1;
while (i <= size) {
int mid = (i + size) / 2;
if (mid == list.get(mid)) {
return true;
}
if (mid < list.get(mid)) {
size = mid - 1;
} else {
i = mid + 1;
}
}
return false;
}
Here is an O(log n) solution.
public static void main(String args[]) {
System.out.println(binarySearch(new int[] {-100, -50, -30, 3, 500, 800}));
System.out.println(binarySearch(new int[] {-100, -50, -30, 42, 500, 800}));
System.out.println(binarySearch(new int[] {-8, 1, 2, 3, 4, 100, 200, 300, 500, 700, 9000}));
}
// Searches for a solution to x[i]=i, returning -1 if no solutions exist.
// The algorithm only works if the array is in ascending order and has no repeats.
// If there is more than one solution there is no guarantee which will
// be returned. Worst case time complexity O(log n) where n is length of array.
public static int binarySearch(int[] x) {
if (x == null || x.length == 0)
return -1;
int low = 0;
if (x[low] == low)
return 0;
else if (x[low] > low)
return -1;
int high = x.length - 1;
if (x[high] == high)
return high;
else if (x[high] < high)
return -1;
while (high - low >= 2) {
int mid = (high + low) / 2;
if (x[mid] == mid)
return mid;
else if (x[mid] > mid)
high = mid;
else low = mid;
}
return -1;
}
public class NewMain1 {
public static void main(String[] args) {
int [] x = {1,2,3,4,5,6};
int value = 7;
boolean check = binarySearch(x,value);
System.out.println(check);
}
public static boolean binarySearch(int [] list , int value) {
int i=0;
int size = list.length - 1;
while (i <= size) {
int mid = (i + size) / 2;
if (value == list[mid]) {
return true;
}
if (value < list[mid]) {
size = mid - 1;
} else {
i = mid + 1;
}
}
return false;
}
I think this could help you

Categories

Resources