当前位置: 首页 > news >正文

【二分搜索题目】

这里写目录标题

  • 多维坐标之间的映射转换
    • 重塑矩阵
    • 搜索二维矩阵
    • 搜索二维矩阵2
  • 寻找峰值
    • 搜索插入位置
    • 寻找峰值
    • 山脉数组的峰值索引
    • 统计目标成绩的出现次数
  • 特殊数组的二分搜索
    • 搜索旋转排序数组

二分搜索的精髓在于快速收缩搜索区间

多维坐标之间的映射转换

重塑矩阵

题目

在这里插入图片描述
在这里插入图片描述

class Solution {
    public int[][] matrixReshape(int[][] mat, int r, int c) {
       int m = mat.length, n = mat[0].length;
        // 如果想成功 reshape,元素个数应该相同
        if (r * c != m * n) {
            return mat;
        }

        int[][] res = new int[r][c];
        for (int i = 0; i < m * n; i++) {
            set(res, i, get(mat, i));
        }
        return res;
    }
    //再res的第index个(从0开始),值为value
    void set(int[][]res,int index,int value){
        int col=res[0].length;
        int i=index/col;
        int j=index%col;
        res[i][j]=value;
    }
    int get(int[][]mat,int index){
        int col=mat[0].length;
        int i=index/col;
        int j=index%col;
        return mat[i][j];
    }
}

搜索二维矩阵

题目
在这里插入图片描述

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int n=matrix.length;
        int m=matrix[0].length;
        int left=0,right=n*m-1,mid=0;
        while(left<=right){
            mid=(left+right)/2;
            int value=getMidValue(matrix,mid);
            if(value<target){
                left=mid+1;
            }else if(value>target){
                right=mid-1;
            }else{
                //找到了
                return true;
            }
        }
        return false;
    }
    int getMidValue(int[][]matrix,int index){
        int col=matrix[0].length;
        int i=index/col;
        int j=index%col;
        return matrix[i][j];
    }
}

搜索二维矩阵2

题目
在这里插入图片描述

class Solution {
    //从右上角开始,像左移动变小,向下移动变大
    public boolean searchMatrix(int[][] matrix, int target) {
        int n=matrix.length;
        int m=matrix[0].length;
        int i=0,j=m-1;
        while(i<n && j>=0){
            if(matrix[i][j]<target){
                //往下
                i++;
            }else if(matrix[i][j]>target){
                //往左
                j--;
            }else{
                //找到了
                return true;
            }
        }
        return false;
    }
}

寻找峰值

搜索插入位置

题目
在这里插入图片描述

class Solution {
    //找到<targe的最大数的index
    public int searchInsert(int[] nums, int target) {
        if(target<=nums[0]){
            return 0;
        }
        int left=0,right=nums.length-1;
        while(left<right){
            int mid=(left+right+1)/2;//求最大,取右边
            if(nums[mid]<target){
                left=mid;
            }else{
                right=mid-1;
            }
        }
      
        return left+1;
    }
}

寻找峰值

题目
在这里插入图片描述
在这里插入图片描述

class Solution {
    //注意:寻找一个峰值, nums[-1] = nums[n] = -∞
    public int findPeakElement(int[] nums) {
        int left=0,right=nums.length-1;
        while(left<right){
            int mid=(left+right)/2;
            if(nums[mid]<nums[mid+1]){
                //峰值在mid的右边
                left=mid+1;
            }else if(nums[mid]>nums[mid+1]){
                //峰值在mid左边,包括mid
                right=mid;
            }
        }
        return left;
    }
}

山脉数组的峰值索引

题目

在这里插入图片描述

跟上面一体类似,考虑mid的周边情况

class Solution {
    //考虑mid的周边情况
    public int peakIndexInMountainArray(int[] arr) {
        int left=0,right=arr.length-1;
        while(left<right){
            int mid=(left+right)/2;
            if(arr[mid]<arr[mid+1]){
                //峰值在mid右边
                left=mid+1;
            }else{
                //峰值在mid的左边,包括mid
                right=mid;
            }
        }
        return left;
    }
}

统计目标成绩的出现次数

题目
在这里插入图片描述

class Solution {
    //思路:寻找小于target的最大值 的index,然后往后遍历数数
    public int countTarget(int[] scores, int target) {
        
        int left=0,right=scores.length-1;
        if(left>right){
            //为空
            return 0;
        }

        while(left<right){
            int mid=(left+right+1)/2;
            if(scores[mid]<target){
                left=mid;
            }else{
                right=mid-1;
            }
        }

        int start=left;
        int count=0;
        for(int i=start;i<scores.length;i++){
            if(scores[i]==target){
                count++;
            }
            
        }
        return count;
    }
}

特殊数组的二分搜索

搜索旋转排序数组

题目
在这里插入图片描述
在这里插入图片描述

class Solution {
 
    public int search(int[] nums, int target) {
        int left=0,right=nums.length-1;
        int leftVaule=nums[left],rightValue=nums[right];
        while(left<=right){
            int mid=(left+right)/2;

            if(nums[mid]==target){
                return mid;
            }
            
            if(nums[mid]>=nums[left]){
                //mid在左边悬崖or没有悬崖了
                if(target<nums[mid] && target>=nums[left]){
                    //target在有序区间[0,mid-1]
                    right=mid-1;
                }else{
                    left=mid+1;
                }
            }else{
                //mid在右边悬崖
                if(target<nums[mid]){
                    right=mid-1;
                }else{
                    if(target<nums[left]){
                        left=mid+1;
                    }else{
                        right=mid-1;
                    }
                }
            }
        }
        return -1;
    }
}

相关文章:

  • 使用nginx+rtmp+ffmpeg实现桌面直播
  • docker 安装 Rabbitmq 详解
  • 机器学习实战(5):决策树与随机森林——直观的分类与回归方法
  • leetcode-414.第三大的数
  • c语言易错题(选择)
  • VMware按照的MacOS升级后无法联网
  • A9. Jenkins Pipeline自动化构建,飞书通知
  • 【Github每日推荐】-- 2024 年项目汇总
  • 网工_IP地址
  • 云计算架构学习之Ansible-playbook实战、Ansible-流程控制、Ansible-字典循环-roles角色
  • 蓝桥杯单片机基础部分——6、555定时器
  • 【学术投稿-第四届材料工程与应用力学国际学术会议(ICMEAAE 2025】材料工程与应用力学的探讨
  • Java中的锁
  • 六、敏捷开发工具:项目管理工具
  • 常用Webpack Loader汇总介绍
  • 【C++】结构体排序+sort(),cmp()参数写法口诀
  • 【时时三省】(C语言基础)三种基本结构和改进的流程图
  • Day01 【苍穹外卖】环境搭建与前后端联调
  • 【Java】泛型与集合篇(二)
  • cesium视频投影
  • 洞天寻隐·学林纪丨玉洞桃源:仇英青绿山水画中的洞天与身体
  • 黄玮接替周继红出任国家体育总局游泳运动管理中心主任
  • 欧派家居:一季度营收降4.8%,目前海外业务整体体量仍较小
  • 上海加力提速推进优化营商环境,明确“十大攻坚突破任务”
  • 探索人类的心灵这件事,永远也不会过时
  • 李云泽:对受关税影响较大、经营暂时困难的市场主体,一企一策提供精准服务