Last active
January 18, 2017 19:02
-
-
Save bdqnghi/3c35a6423728cc205578810cb913fe5a to your computer and use it in GitHub Desktop.
Kth smallest number of multiple sorted arrays
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.smu.software; | |
import java.util.Arrays; | |
/** | |
* Hello world! | |
*/ | |
public class App { | |
public static void main(String[] args) { | |
// int[] A = {3, 4, 5, 6, 9, 10}; | |
// | |
// int[] B = {6, 7, 8, 11, 15, 17, 20, 25}; | |
// //int temp[] = Arrays.copyOfRange(A,0,6); | |
// | |
// System.out.println(findKSmallestNumber(A, B, 9)); | |
int[] list1 = {3, 4, 5, 6, 9, 12}; | |
int[] list2 = {2, 7, 8, 11, 15, 17}; | |
int[][] list_array = {list1, list2}; | |
//// int[] list1 = new int[] { 3, 4, 10, 23, 45, 55, 56, 58, 60, 65 }; | |
//// int[] list2 = new int[] { 3, 3, 3, 15, 16, 28, 50, 70, 71, 72 }; | |
// int k = 9; | |
// | |
// int kthSmallest = kthSmallest(list1, list2, k); | |
// System.out.println(k + "th smallest is " + kthSmallest); | |
System.out.println(rank(list1, 13, 0, list1.length - 1)); | |
System.out.println(rank(list2, 15, 0, list1.length - 1)); | |
System.out.println(rankOfMultipleList(list_array, 15)); | |
} | |
static boolean isOdd(int i) { | |
if ((i & 1) == 0) { | |
return false; | |
} | |
return true; | |
} | |
static int rankOfMultipleList(int[][] array2D, int n) { | |
int biggerThan = 0; | |
for (int[] array : array2D) { | |
biggerThan += rank(array, n, 0, array.length-1); | |
} | |
return biggerThan; | |
} | |
static int rank(int array[], int n, int left, int right) { | |
int mid = (left + right) / 2; | |
if (array[mid] == n || left == right) { | |
if (mid == array.length - 1) { | |
return mid + 1; | |
} | |
return mid; | |
} | |
if (array[mid] > n) { | |
return rank(array, n, 0, mid); | |
} | |
return rank(array, n, mid + 1, right); | |
} | |
static int findKSmallestNumber(int[] A, int[] B, float K) { | |
int sizeA = A.length; | |
int sizeB = B.length; | |
int halfK = (int) Math.ceil(K / 2); | |
if (sizeA > sizeB) | |
return findKSmallestNumber(B, A, K); | |
if (sizeA == 0 && sizeB > 0) | |
return B[((int) (K - 1))]; // due to zero based index | |
if (K == 1) { | |
return Math.min(A[0], B[0]); | |
} | |
int i = Math.min(sizeA, halfK); | |
int j = Math.min(sizeB, halfK); | |
if (A[i - 1] < B[j - 1]) { | |
return findKSmallestNumber(Arrays.copyOfRange(A, i, sizeA), Arrays.copyOfRange(B, 0, j), K - i); | |
} else { | |
return findKSmallestNumber(Arrays.copyOfRange(A, 0, i), Arrays.copyOfRange(B, j, sizeB), K - j); | |
} | |
} | |
public static int kthSmallest(int[] A, int[] B, int k) { | |
if (A == null || B == null) { | |
throw new IllegalArgumentException("Arrays cannot be null!"); | |
} | |
int a = A.length; | |
int b = B.length; | |
if (k < 1 || k > a + b) { | |
throw new IllegalArgumentException("k is not within range!"); | |
} | |
int minSizeA = Math.max(0, k - b); | |
int maxSizeA = Math.min(a, k); | |
while (minSizeA <= maxSizeA) { | |
int sizeA = minSizeA + (maxSizeA - minSizeA) / 2; | |
int sizeB = k - sizeA; | |
int indexA = sizeA - 1; | |
int indexB = sizeB - 1; | |
int indexANext = sizeA; | |
int indexBNext = sizeB; | |
int valA = (indexA < 0) ? Integer.MIN_VALUE : A[indexA]; | |
int valB = (indexB < 0) ? Integer.MIN_VALUE : B[indexB]; | |
int valANext = (indexANext >= a) ? Integer.MAX_VALUE : A[indexANext]; | |
int valBNext = (indexBNext >= b) ? Integer.MAX_VALUE : B[indexBNext]; | |
if (valA <= valBNext && valB <= valANext) { | |
return Math.max(valA, valB); | |
} else if (valA > valBNext) { | |
maxSizeA = sizeA - 1; | |
} else { | |
minSizeA = sizeA + 1; | |
} | |
} | |
return 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment