文章目录
- 描述
- 主要代码
- 全部代码
- 运行结果
- 总结
二分法不一定只能用在有序数组中。
描述
leetcode:162
主要代码
//二分法查找峰值
public static int findPeakElement(int[] arr){
if (arr.length == 1){//randomArray()不会出现arr = null的情况
return 0;
}
//先检查 0 和 arr.length-1是不是峰值
if(arr[0]> arr[1]){
return 0;
}if(arr[arr.length-2] < arr[arr.length-1]){
return arr.length-1;
}
//第一个数和最后一个数肯定不是峰值,所以范围直接从1开始
//这样m != 0恒成立,m-1不会越界
int l = 1;
int r = arr.length-2;
int m = l + ((r - l)>>1);
int ans = -1;
//二分法寻找峰值
while (l <= r){
if (arr[m-1] > arr[m]){
r = m-1;
}else if (arr[m]<arr[m+1]){
l = m+1;
}else{
ans = m;
break;
}
}
return ans;
}
全部代码
import java.util.Arrays;
/**
* @Author: ggdpzhk
* @CreateTime: 2024-07-27
* 特别的二分:寻找峰值问题
* leetcode:162
*/
//二分法不一定非得是 有序数组。比如在进行峰值查找问题时,就不用给数组排序
//一个无序数组不可能没有峰值
public class _006_03_FindPeakElement {
/*
先找0位置,看是不是峰点,如果是返回数组下标
找arr.length-1的位置,看看是不是峰点,如果是返回数组下标
二分法找中点,与中点两侧进行对比,看是不是中点,如果是返回数组下标
如果不是,根据上升下降的起伏,判断中点左侧还说右侧有峰点,继续二分
* */
public static void main(String[] args) {
int N = 10;
int V = 20;
int testTimes = 5;
for (int i = 0; i < testTimes; i++) {
System.out.println("这是第"+(i+1)+"次测试");
int n = (int) (Math.random() * N + 1);
int[] arr = randomArray(n, V);
System.out.println(Arrays.toString(arr));
System.out.println("一个峰值是"+arr[findPeakElement(arr)]);
System.out.println("____________________________");
}
}
public static int[] randomArray(int n,int V){
int[] arr = new int[n];
for (int i = 0; i < arr.length;i++){
arr[i] =(int)(Math.random()*V+1);
}
return arr;
}
//二分法查找峰值
public static int findPeakElement(int[] arr){
if (arr.length == 1){//randomArray()不会出现arr = null的情况
return 0;
}
//先检查 0 和 arr.length-1是不是峰值
if(arr[0]> arr[1]){
return 0;
}if(arr[arr.length-2] < arr[arr.length-1]){
return arr.length-1;
}
int l = 1;
int r = arr.length-2;
int m = l + ((r - l)>>1);
int ans = -1;
//二分法寻找峰值
while (l <= r){
if (arr[m-1] > arr[m]){
r = m-1;
}else if (arr[m]<arr[m+1]){
l = m+1;
}else{
ans = m;
break;
}
}
return ans;
}
}
运行结果
总结
- if-else
- 是二选一,条件结果是true或者false,没有第三种情况
- 只会运行一个代码块,另一个直接跳过不执行
- if - if
- 条件结果是可能多种情况。代码块可能都会运行,也可能都不会运行。