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?
Related
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);
}
}
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);
}
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
I am attempting to create a mergeSort method without using recursion. It almost works perfectly except it doesn't sort the last element of my array for some reason. Any help is greatly appreciated!
Example Output:
[23, 94, 69, 32, 99, 20, 17, 88, 22, 88]
MergeSort took 7.134364 milliseconds
original: [17, 20, 22, 23, 32, 69, 88, 88, 94, 99] //Arrays.sort
working1: [17, 20, 22, 23, 32, 68, 88, 94, 99, 88] //MergeSort
There is an Error
import java.util.*;
public class MergeSort {
public static void mergeSortExplicit(int[] arr, int n){
int size;
int left;
for (size = 1; size <= n-1; size = 2*size) {
for (left = 0; left < n-1; left += 2*size) {
int mid = left + size - 1;
int right = Math.min(left + 2*size - 1, n-1);
merge(arr, left, mid, right);
}
}
}
private static void merge(int[] array, int start, int mid, int end) {
int leftIndex = start;
int rightIndex = mid + 1;
int[] temp = new int[end - start + 1];
int tempIndex = 0;
while (leftIndex <= mid && rightIndex <= end) {
temp[tempIndex++] = (array[leftIndex] < array[rightIndex]) ? array[leftIndex++] : array[rightIndex++];
}
if (leftIndex <= mid) {
System.arraycopy(array, leftIndex, temp, tempIndex, mid - leftIndex + 1);
}
if (rightIndex <= end) {
System.arraycopy(array, rightIndex, temp, tempIndex, end - rightIndex + 1);
}
System.arraycopy(temp, 0, array, start, end - start + 1);
}
public static final void main(String[] args) {
Random random = new Random();
int[] original = new int[10];
for (int i = 0; i < original.length; i++) {
original[i] = random.nextInt(original.length * 10);
}
int[] working1 = new int[original.length];
System.arraycopy(original, 0, working1, 0, original.length);
long startTime = 0, endTime = 0;
startTime = System.nanoTime();
Arrays.sort(original);
endTime = System.nanoTime();
System.out.println("Arrays.sort() took " + ((endTime - startTime) / 1E6) + " milliseconds");
startTime = System.nanoTime();
//mergeSort(working1, 0, working1.length - 1);
System.out.println(Arrays.toString(working1));
mergeSortExplicit(working1, working1.length - 1);
endTime = System.nanoTime();
System.out.println("MergeSort took " + ((endTime - startTime) / 1E6) + " milliseconds");
if (!Arrays.equals(original, working1)) {
System.out.println("original: " + Arrays.toString(original));
System.out.println("Working1: " + Arrays.toString(working1));
System.out.println("There is an error");
} else {
System.out.println("Sorts Work!");
}
}
}
While just going through, I can see that you are calling following function in main :
mergeSortExplicit(working1, working1.length - 1);
which means you are already calling the function with 1 less size than whatever is the actual size and later again inside that called function, in the following loop :
for (size = 1; size <= n-1; size = 2*size)
you are again considering 1 less then what you have passed.
Please remove any one of the above decrements, then it should work fine.
Here's the original question
Give you an array which has n integers,it has both positive and
negative integers.Now you need sort this array in a special way.After
that,the negative integers should in the front,and the positive
integers should in the back.Also the relative position should not be
changed.
eg. -1 1 3 -2 2 ans: -1 -2 1 3 2.
My Java code (translated from Wikipedia's pseudocode)
package ThreewayPartition;
import java.util.Arrays;
public class ThreewayPartition {
public void sort(int[] input, int mid) {
int i=0;
int j=0;
int n = input.length - 1;
while (j <= n) {
if (input[j] < mid) {
swap(input, i, j);
i++;
j++;
} else if (input[j] > mid) {
swap(input, j, n);
n--;
} else {
j++;
}
}
}
private void swap(int[] arr, int j, int k) {
int tmp = arr[j];
arr[j] = arr[k];
arr[k] = tmp;
}
public static void main(String[] args) {
int[] input = {-1, 1, 3, -2, 2};
ThreewayPartition twp = new ThreewayPartition();
twp.sort(input, 0);
System.out.println(Arrays.toString(input));
}
}
I get this output: [-1, -2, 3, 2, 1] instead of [-1, -2, 1, 3, 2]
Your swap() method is swapping elements, not shifting.
You can modify the sort method as shown below -
public void sort(int[] input, int mid) {
int n = input.length - 1;
int i=0;
int tmpvar;
while (n >= i) {
if(input[n] < mid) {
tmpvar = input[n];
System.arraycopy(input, 0, input, 1, n);
input[0] = tmpvar;
i++;
} else {
n--;
}
}
}
Probably there is nothing wrong with implementation - just Dutch national flag inplace partition is not stable.
I had a look at Wikipedia's pseudocode and I noticed that mid is used incorrectly in sort(). It should be used as a value, i.e, input[mid].
That being said Dutch National Flag algorithm is not stable and will not satisfy the constraint in the question:
the relative position should not be changed
However, it's important to mention that the problem is a variant of the DNF algorithm.
So you are looking for something along the following lines:
import java.util.Arrays;
public class ThreewayPartition{
public static void sort(int[] A, int mid) {
int startIndex = 0;
for (int i = 0; i < A.length; i++) {
if (A[i] <= mid) {
int temp = A[i];
for (int j = i; j > startIndex; j--) {
A[j] = A[j-1];
}
A[startIndex] = temp;
if (temp < mid) startIndex++;
}
}
}
public static void main(String[] args) {
int[] input = {-1, 1, 3, -2, 2};
ThreewayPartition twp = new ThreewayPartition();
twp.sort(input, 0);
System.out.println(Arrays.toString(input)); // [-1, -2, 1, 3, 2]
}
}
Please note that the code's time complexity is O(n*n).
A more efficient, time complexity O(n), and simpler to understand:
import java.util.Arrays;
public class ThreewayPartition{
public static void sort(int[] A, int mid) {
for (int i = A.length - 1; i > 0; i--) {
if (A[i] <= mid && A[i - 1] > mid) {
swap(A, i, i-1);
}
}
}
private static void swap(int[] arr, int j, int k) {
int tmp = arr[j];
arr[j] = arr[k];
arr[k] = tmp;
}
public static void main(String[] args) {
int[] input = {-1, 1, 3, -2, 2};
ThreewayPartition twp = new ThreewayPartition();
twp.sort(input, 0);
System.out.println(Arrays.toString(input)); // [-1, -2, 1, 3, 2]
}
}