原创转载请注明出处:http://agilestyle.iteye.com/blog/2273610
Binary Search原理
package org.fool.test;
public class BinarySearch {
public static int binarySearch(int[] nums, int num) {
int low = 0;
int high = nums.length - 1;
while (low <= high) {
int mid = (low + high) / 2;
if (num > nums[mid]) {
low = mid + 1;
} else if (num < nums[mid]) {
high = mid - 1;
} else {
return mid;
}
}
return -1;
}
public static void main(String[] args) {
int[] nums = { 12, 23, 34, 45, 56, 67, 77, 89, 90 };
System.out.println(binarySearch(nums, 12));
System.out.println(binarySearch(nums, 45));
System.out.println(binarySearch(nums, 67));
System.out.println(binarySearch(nums, 89));
System.out.println(binarySearch(nums, 99));
}
}
get square root of a number
核心思想:二分查找
1.define an initial range of (start, end)
2.keep testing mid^2 to approach value
3.update start or end to mid
4.stop when certain precision is achieved or exact square root is computed
package org.fool.java.test;
public class SqrtTest {
public static void main(String[] args) {
System.out.println("sqrt of 50 is " + sqrt(50));
System.out.println("sqrt of 81 is " + sqrt(81));
System.out.println("sqrt of 99 is " + sqrt(99));
}
private static double sqrt(double a) {
if (a < 0) {
return -1;
}
if (a == 0 || a == 1) {
return a;
}
double precision = 0.00000001;
double start = 0;
double end = a;
// define these 2 start/end values because usually 0 < sqrt(a) < a
// however, if a < 1, then 0 < a < sqrt(a)
if (a < 1) {
end = 1;
}
// define a loop to continue if the precision is not yet achieved
while (end - start > precision) {
double mid = (start + end) / 2;
double midSqr = mid * mid;
if (midSqr == a) {
return mid; // the exact sqrt value
} else if (midSqr < a) {
start = mid; // shift focus to bigger half
} else {
end = mid; // shift focus to smaller half
}
}
// if not find the exact sqrt value, return the approximated value with the defined precision
return (start + end) / 2;
}
}
Console Output
Count Occurance of a given number in sorted array
solution 1: linear search in O(N)
solution 2: binary search(preferred)
need to add boundary checking for each sub-array
package org.fool.java.test;
public class NumberOccurrenceTest {
public static void main(String[] args) {
int[] nums = {1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 8, 9};
System.out.println("Occurrence of num 2 is " + getOccurrence(2, nums, 0, nums.length - 1));
System.out.println("Occurrence of num 6 is " + getOccurrence(6, nums, 0, nums.length - 1));
System.out.println("Occurrence of num 7 is " + getOccurrence(7, nums, 0, nums.length - 1));
System.out.println("Occurrence of num 17 is " + getOccurrence(17, nums, 0, nums.length - 1));
}
private static int getOccurrence(int k, int[] numbers, int startIndex, int endIndex) {
if (endIndex < startIndex) {
return 0;
}
if (numbers[startIndex] > k) { // smallest element is larger than k
return 0;
}
if (numbers[endIndex] < k) { // largest element is smaller than k
return 0;
}
if (numbers[startIndex] == k && numbers[endIndex] == k) { // if all elements are k
return endIndex - startIndex + 1;
}
int midIndex = (startIndex + endIndex) / 2;
// a sub-array may possibly contain some other k
if (numbers[midIndex] == k) {
return 1 + getOccurrence(k, numbers, startIndex, midIndex - 1) + getOccurrence(k, numbers, midIndex + 1, endIndex);
} else if (numbers[midIndex] > k) { // only smaller half may contain k
return getOccurrence(k, numbers, startIndex, midIndex - 1);
} else { // only bigger half may contain k
return getOccurrence(k, numbers, midIndex + 1, endIndex);
}
}
}
Console Output
Find the 1st index of given number in a sorted array allowing duplicates
核心思想:二分查找
package org.fool.java.test;
public class FindFirstIndexTest {
public static void main(String[] args) {
int[] nums = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 6, 7, 8, 8, 9};
System.out.println("First index of number 1 is " + getFirstIndex(nums, 1, 0, nums.length - 1));
System.out.println("First index of number 2 is " + getFirstIndex(nums, 2, 0, nums.length - 1));
System.out.println("First index of number 3 is " + getFirstIndex(nums, 3, 0, nums.length - 1));
System.out.println("First index of number 4 is " + getFirstIndex(nums, 4, 0, nums.length - 1));
System.out.println("First index of number 5 is " + getFirstIndex(nums, 5, 0, nums.length - 1));
System.out.println("First index of number 8 is " + getFirstIndex(nums, 8, 0, nums.length - 1));
}
// define a same header as a normal binary search
// nums are the sorted array
// a is the number we are looking for
// start and end are the two index values to keep track of the current focus sub-array
private static int getFirstIndex(int[] nums, int a, int start, int end) {
if (end < start) {
return -1;
}
if (nums[start] > a) {
return -1;
}
if (nums[end] < a) {
return -1;
}
// need to check if first element is a
if (nums[start] == a) {
return start;
}
int mid = (start + end) / 2;
if (nums[mid] == a) {
// we have 2 choices, either mid position is candidate, or the index we find in the left half
int leftIndex = getFirstIndex(nums, a, start, mid - 1); // recursive call
return leftIndex == -1 ? mid : leftIndex;
} else if (nums[mid] > a) { // which means a can only appear in the left half
return getFirstIndex(nums, a, start, mid - 1);
} else { // which means only possible in the right half
return getFirstIndex(nums, a, mid + 1, end);
}
}
}
Console Output
Reference
https://www.youtube.com/watch?v=XvsQ68jUc2U&index=50&list=PLlhDxqlV_-vkak9feCSrnjlrnzzzcopSG
https://www.youtube.com/watch?v=W8923B642PQ&list=PLlhDxqlV_-vkak9feCSrnjlrnzzzcopSG&index=49
https://www.youtube.com/watch?v=bvzJw9CVmkI&index=45&list=PLlhDxqlV_-vkak9feCSrnjlrnzzzcopSG