二分查找第二弹

简介: 二分查找第二弹

力扣852.山脉数组的峰顶索引

峰顶之前的全部比他小,峰顶之后的也比他小,把小于等于和大于分成两段

class Solution {
    public int peakIndexInMountainArray(int[] arr) {
        //第一个和最后一个都不是峰值
      int left=1;
      int right=arr.length-2;
      while(left<right){
          int med=left+(right-left+1)/2;
          if(arr[med]>arr[med-1]){
              left=med;
          }else{
              right=med-1;
          }
      }
          return left;
      
    }
}

力扣162.寻找峰值

暴力解法,从第一个位置开始,一直向后面走,然后分类讨论即可。

这种没有顺序的,我们该如何使用二分呢?

二段性

峰值一定一个在左边,另一个一定在右边

代码怎么写,怎么规定是我们决定的,你的思想决定你的想法。

这里我其实一直区分不出来什么时候是+1,-1什么时候是正好=med,我的想法是,你看你需要什么,这道题是要求峰值,峰值一定是最大的那个是数字,那么假如代码里面x>m

你肯定是要保留这个x,那么你就让right/left=x,因为你是要保留大的,反之也一样

class Solution {
    public int findPeakElement(int[] nums) {
    int left=0;
    int right=nums.length-1;
    while(left<right){
        int med=left+(right-left)/2;
        if(nums[med]>nums[med+1]){
            right=med;
        }else{
            left=med+1;
        }}
        return left;
    }
}

方法2:(一样的思想,只不过操作不同,但是大同小异罢了)

class Solution {
   public static int findPeakElement(int[] nums) {
        int left=0;
        int right=nums.length-1;
        while(left<right){
            int med=left+(right-left+1)/2;
            if(nums[med]>nums[med-1]){
                left=med;
            }else{
                right=med-1;
            }}
        return left;
    }
}

力扣153.寻找旋转排序数组中的最小值


以D为参照点,如果说我的nums[n-1]是这个D点,那么比D点大的,就一定要往右边去(因为右边较小),比D小的就一定往左边来。(假如D是最大的,那么他就会一直往左边走,也是符合理想的)

那我我们想一想,假如说是以A为参照点,我们该怎么办呢?,nums[mid]比A大,那么就是right放在mid的右边,假如比A小那么left去找mid的右边

以D为参照点,推荐是以D为参照点处理,推荐,以D为参照点,划分的更加明确,是比D大,和比D小两个阶段,比D大,就可以直接往左边移动到比D小的,比D小,可以往左移动看有没有比D更小的。

class Solution {
    public int findMin(int[] nums) {
        int left=0;
        int right=nums.length-1;
        int x=nums[nums.length-1];
     for(int i=0;i<nums.length;i++){
         int mid=left+(right-left)/2;
         if(nums[mid]>x){
             left=mid+1;
         }else{
             right=mid;
         }
     }
    
     return nums[left];
    }
}

一样的原理,但是有特殊情况

以A为参照点处理。

两点细节,比D点为参照点多两个条件

  public static int findMin(int[] nums) {
        int left=0;
        int right=nums.length-1;
        int x=nums[0];
        if(nums.length==1){return nums[0];}
        if(nums[0]<nums[right]){
            return nums[0];
        }
        for(int i=0;i<nums.length;i++){
            int mid=left+(right-left)/2;
            if(nums[mid]>=x){
                left=mid+1;
            }else{
                right=mid;
            }
        }
 
        return nums[left];
    }


力扣剑指Offer53.0-n-1缺失的数字

直接拿事例理解

[0,1,3]缺少一个2

[0,1,2,3,4,5,6,7,9]缺少一个8

相关文章
|
1月前
|
算法
二分查找第一弹
二分查找第一弹
|
2月前
|
算法 C++
c++算法学习笔记 (15) 单调栈与单调队列
c++算法学习笔记 (15) 单调栈与单调队列
|
1月前
前缀和第一弹
前缀和第一弹
|
1月前
|
存储
前缀和第二弹
前缀和第二弹
|
1月前
|
测试技术
深入理解数据结构第二弹——二叉树(2)——堆排序及其时间复杂度
深入理解数据结构第二弹——二叉树(2)——堆排序及其时间复杂度
22 0
|
1月前
|
存储 搜索推荐
深入了解数据结构第四弹——排序(1)——插入排序和希尔排序
深入了解数据结构第四弹——排序(1)——插入排序和希尔排序
15 0
|
1月前
|
搜索推荐
深入理解数据结构第五弹——排序(2)——快速排序
深入理解数据结构第五弹——排序(2)——快速排序
13 0
|
2月前
|
算法 搜索推荐
LeetCode刷题---215. 数组中的第K个最大元素(双指针,快速选择)
LeetCode刷题---215. 数组中的第K个最大元素(双指针,快速选择)
|
11月前
|
索引
【剑指Offer】--->详解二分查找相关练习(二)
【剑指Offer】--->详解二分查找相关练习(二)
56 1
|
11月前
|
搜索推荐
七个常用的排序算法---快排\归排\希尔\插入\选择\冒泡\堆排(一)
七个常用的排序算法---快排\归排\希尔\插入\选择\冒泡\堆排(一)
62 0