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

【二分搜索题目】

这里写目录标题

  • 多维坐标之间的映射转换
    • 重塑矩阵
    • 搜索二维矩阵
    • 搜索二维矩阵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;
    }
}

http://www.kler.cn/a/552208.html

相关文章:

  • [代码调试]安装Text2Image(stable diffusion)模型环境的踩坑记录
  • 【Go | 从0实现简单分布式缓存】-2:HTTP服务端与一致性哈希
  • cv2库的使用及图像预处理02
  • Linux——Centos的安装与配置
  • WebSocket 小白快速入门(2025)
  • 随机生成多孔介质matlab程序
  • MySQL中count(1)和count(*) 的区别
  • 基于Java+Swing+Mysql实现旅游管理信息系统
  • 基于 Spring Boot 的 “宠物领养系统” 系统的设计与实现
  • 23种设计模式 - 建造者模式
  • JUC并发—6.AQS源码分析二
  • CDN进阶学习<->
  • Git Pull 报错解决方案:fatal: Need to specify how to reconcile divergent branches
  • HarmonyOS4-工具安装
  • 【Linux Redis】关于用docker拉取Redis后,让虚拟机运行起来redis,并使得其可以连接到虚拟机外的navicat。
  • leaflet前端初始化项目
  • 【ARTS】【LeetCode-977】有序数组的平方
  • 单元测试整理
  • 2023年区块链职业技能大赛——区块链应用技术(一)模块一
  • Ubuntu 24或最新Ubuntu 安装 英伟达显卡驱动