1.二分法
1.1 有序数组中找到num
思路
代码
package com.biao.class3;
import java.util.Arrays;
public class Code01_BSExist {
//arr保证有序
// 二分法查找
public static boolean find(int[] arr,int num){
if (arr == null || arr.length == 0){
return false;
}
int L = 0;
int R = arr.length - 1;
while ( L < R ){
int mid = ( L + R ) / 2;
if (num == arr[mid]){
return true;
}else if( num < arr[mid]){
R = mid -1;
}else{
L = mid + 1;
}
}
return false;
}
// 暴力测试
public static boolean test(int[] arr , int num){
for (int i = 0; i < arr.length; i++) {
if ( num == arr[i]){
return true;
}
}
return false;
}
// for test
public static int[] generateRandomArray(int maxSize,int maxValue){
int[] arr = new int[(int) ((maxSize +1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int)((maxValue + 1) * Math.random()) - (int)(maxValue * Math.random());
}
return arr;
}
public static void main(String[] args) {
int testTime = 50000;
int maxSize = 10;
int maxValue = 100;
boolean succeed = true;
for (int i = 0; i < testTime; i++) {
int[] arr = generateRandomArray(maxSize,maxValue);
Arrays.sort(arr);
int value = (int) ((maxValue+1)*Math.random()) - (int)(maxValue * Math.random());
if (test(arr,value) != find(arr,value)){
succeed = false;
break;
}
System.out.println(succeed ? "success" : "not success");
}
}
}
1.2 有序数组中找到>=num最左的位置
代码:
package com.biao.class3;
import java.util.Arrays;
public class Code2_BSNearLeft {
// arr有序的,>=num zuizuode
public static int mostLeftNoLessNumIndex(int[] arr,int num){
if (arr == null || arr.length == 0 ){
return -1;
}
int L = 0;
int R = arr.length - 1;
// 找到的下标值
int ans = -1;
while (L <= R){
int mid = (L + R)/2;
if (arr[mid] >= num){
ans = mid;
R = mid - 1;
}else{
L = mid + 1;
}
}
return ans;
}
// 遍历test
public static int test(int[] arr,int num){
for (int i = 0; i < arr.length; i++) {
if (arr[i] >= num){
return i;
}
}
return -1;
}
// for test
public static int[] generateRandomArray(int maxSize,int maxValue){
int[] arr = new int[(int)((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int)((maxValue + 1) * Math.random() - (maxValue - 1) * Math.random());
}
return arr;
}
public static void printArray(int[] arr){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
public static void main(String[] args) {
int testTime = 500000;
int maxSize = 10;
int maxValue = 100;
boolean success = true;
for (int i = 0; i < testTime; i++) {
int arr[] = generateRandomArray(maxSize,maxValue);
Arrays.sort(arr);
int num = (int)((maxValue + 1) * Math.random()) - (int)((maxValue - 1) * Math.random()) ;
if (test(arr,num) != mostLeftNoLessNumIndex(arr,num)){
printArray(arr);
System.out.println("num:"+num);
System.out.println(test(arr,num));
System.out.println(mostLeftNoLessNumIndex(arr,num));
success = false;
break;
}
System.out.println(success ? "nice" : "no");
}
}
}
1.3 局部最小值问题
package com.biao.class3;
public class Code04_BSAwesome {
//数组整体无序
//相邻的数不相等
public static int oneMinIndex(int[] arr){
if (arr.length == 0 || arr == null){
return -1;
}
int N = arr.length;
//数组一个数直接返回
if (N == 1){
return 0;
}
//判断两个数情况
if (arr[0] < arr[1]){
return 0;
}
if (arr[N - 2] > arr[N - 1]){
return N - 1;
}
int L = 0;
int R = N - 1;
//注意边界
while (L < R - 1){
int mid = (L + R) / 2;
if (arr[mid] < arr[mid - 1] && arr[mid] < arr[mid + 1]){
return mid;
}else {
if (arr[mid] > arr[mid-1]){
R = mid - 1;
}else{
L = mid + 1;
}
}
}
return arr[L] < arr[R] ? L : R;
}
//生成随机数组,且相邻不相等
public static int[] randomArray(int maxLen,int maxValue){
int len = (int)(Math.random() * maxLen);
int[] arr = new int[len];
if (len > 0){
arr[0] = (int)(Math.random()*maxValue);
for (int i = 1; i < len; i++) {
do {
arr[i] = (int)(Math.random()*maxValue);
}while (arr[i] == arr[i - 1]);
}
}
return arr;
}
//用于测试
public static boolean check(int[] arr,int minIndex){
if (arr.length == 0){
return minIndex == -1;
}
int left = minIndex - 1;
int right = minIndex + 1;
boolean leftBigger = left >= 0 ? arr[left] > arr[minIndex] : true;
boolean rightBigger = right < arr.length ? arr[right] > arr[minIndex] : true;
return leftBigger && rightBigger;
}
//打印数组
public static void printArray(int[] arr) {
for (int num : arr) {
System.out.print(num + " ");
}
System.out.println();
}
public static void main(String[] args) {
int maxLen = 100;
int maxValue = 200;
int testTime = 100000;
System.out.println("测试开始");
for (int i = 0; i < testTime; i++) {
int[] arr = randomArray(maxLen,maxValue);
int ans = oneMinIndex(arr);
if (!check(arr, ans)) {
printArray(arr);
System.out.println(ans);
break;
}
}
System.out.println("测试结束");
}
}