首页 > 编程语言 >Java学习—二分法查找(二)

Java学习—二分法查找(二)

时间:2023-11-21 23:32:47浏览次数:41  
标签:Java nums int 峰值 二分法 length 查找 return left

BM18 二维数组中的查找

描述

在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

[

[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]

]

给定 target = 7,返回 true。

给定 target = 3,返回 false。


输入:

7,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]

返回值:

true

说明:

存在7,返回true

输入:

1,[[2]]

返回值:

false


题目的主要信息:
  • 矩阵的行元素和列元素都是有序的,从左到右递增,从上到下递增,完全递增元素不会有重复
  • 找到矩阵中有没有给定元素即可

方法1:二分查找(推荐使用)

知识点:分治

分治即“分而治之”,“分”指的是将一个大而复杂的问题划分成多个性质相同但是规模更小的子问题,子问题继续按照这样划分,直到问题可以被轻易解决;“治”指的是将子问题单独进行处理。经过分治后的子问题,需要将解进行合并才能得到原问题的解,因此整个分治过程经常用递归来实现。

具体做法:

  • step 1:首先获取矩阵的两个边长,判断特殊情况。
  • step 2:首先以左下角为起点,若是它小于目标元素,则往右移动去找大的,若是他大于目标元素,则往上移动去找小的。
  • step 3:若是移动到了矩阵边界也没找到,说明矩阵中不存在目标值。
public class Solution {
    public boolean Find(int target, int [][] array) {
        //优先判断特殊
        if(array.length == 0)  
            return false;
        int n = array.length;
        if(array[0].length == 0)  
            return false;
        int m = array[0].length;
        //从最左下角的元素开始往左或往上
        for(int i = n - 1, j = 0; i >= 0 && j < m; ){ 
            //元素较大,往上走
            if(array[i][j] > target)   
                i--;
            //元素较小,往右走
            else if(array[i][j] < target) 
                j++;
            else
                return true;
        }
        return false;
    }
}


方法2:暴力法

1. 分析

挨个遍历数组,如果找到就返回 true

public class Solution {
    public boolean Find(int target, int [][] array) {
        for(int i=0;i<array.length;i++){
            for(int j=0;j<array[0].length;j++){
                if(array[i][j] == target){
                    return true;
                }
            }
        }
        return false;
    }
}




BM19 寻找峰值

给定一个长度为n的数组nums,请你找到峰值并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个所在位置即可。

1.峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于

如输入[2,4,1,2,7,8,4]时,会形成两个山峰,一个是索引为1,峰值为4的山峰,另一个是索引为5,峰值为8的山峰,如下图所示:

Java学习—二分法查找(二)_数组

示例1

输入:

[2,4,1,2,7,8,4]

返回值:

1

说明:

4和8都是峰值元素,返回4的索引1或者8的索引5都可以

示例2

输入:

[1,2,3,1]

返回值:

2

说明:

3 是峰值元素,返回其索引 2

</>代码

下面进行分析:

1、首先理解题目:峰值,即当前值左右两边的值都比它小,边界只要一边比它小即可

2、分析:

(1)如果只有一个数值,直接返回0;

(2)如果有两个数值,谁大就返回谁的下标;

(3)考虑边界:

        a. 左边界,即下标为0的数值,只要它比右边的数值大,那它就是峰值;题目要求只要找出一个峰值就行了,因此这个条件可以优先判断,满足返回即可;

        b. 右边界,即最后一个数值,只要它比左边的数值大,那它就是峰值;剩下所有数值都遍历过之后无峰值才判断该边界条件;



public class Solution {
    public int findPeakElement (int[] nums) {
        return findPeek(nums, 0, nums.length - 1);
    }

    public int findPeek(int[] nums, int left, int right) {
        if (left == right) {  // 区间只有一个元素时进行判断
            if (nums.length == 1) {  // 数组本来就一个元素,则一定是峰值
                return left;
            } else {  // 数组大于一个元素
                if (left > 0 && left < nums.length - 1) {  // 该元素位于中间
                    if (nums[left] > nums[left - 1] && nums[left] > nums[left + 1]) {
                        return left;
                    }
                } else if (left == 0) {  // 该元素位于左侧
                    if (nums[left] > nums[left + 1]) {
                        return left;
                    }
                } else if (right == nums.length - 1) {  // 该元素位于右侧
                    if (nums[right] > nums[right - 1]) {
                        return right;
                    }
                }
            }
        } else {  // 区间大于一个元素时分治
            int mid = (left + right) >> 1;
            int lres = findPeek(nums, left, mid);  // 找左侧的峰值
            int rres = findPeek(nums, mid + 1, right);  // 找右侧的峰值
            if (lres != -1) return lres;
            if (rres != -1) return rres;
        }

        return -1; // 找不到峰值返回-1
    }
}


import java.util.*;
public class Solution {
    public int findPeakElement (int[] nums) {
        // write code here
        // 两种特殊情况,第一种length为1,
        if (nums.length == 1) return 0;
        //第二种峰值在尾部
        if (nums[nums.length - 1] > nums[nums.length - 2]) return nums.length - 1;
        //峰值在中间
        for (int i = 1; i < nums.length - 1; i++) {
            if (nums[i - 1] < nums[i] && nums[i + 1] < nums[i]) {
                return i;
            }
        }
        //峰值在头部
        return 0;
    }
}



// *****暴力求解完事******
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @return int整型
     */
    public int findPeakElement (int[] nums) {
        // write code here
        if(nums.length == 2)
            if(nums[0] > nums[1])
                return 0;
            else return 1;    
        for(int i = 1; i < nums.length-1; i++){
            if(nums[i] > nums[i+1] && nums[i] > nums[i-1])
            return i;
            if(nums[i]< nums[i+1] && i == nums.length-2)
            return i+1;
        }
        return 0;
    }
}



标签:Java,nums,int,峰值,二分法,length,查找,return,left
From: https://blog.51cto.com/u_15520037/8507493

相关文章

  • 解决问题:Unable to start embedded container; nested exception is java.lang.NoSuch
    因为有重复的jar原因:springboot有自己的tomcat运行环境我们又在构件路径中添加了tomcat解决方法:把项目构件路径中的tomcat给移除 ......
  • 前端学习-JavaScript学习-js基础05
    学习教程:黑马程序员视频链接对象了解<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Docum......
  • java 内部类
    packagenet.elaina.innerclass01;publicclassCar{StringcarName;intcarAge;StringcarColor;publicvoidshow(Carthis){//是打印调用者车的名字:宾利System.out.println(this.carName);//???在代码中有没有发动机......
  • Java的Integer.bitCount()源码分析
    本文部分参考:https://blog.csdn.net/weixin_42092787/article/details/106607426常规解法对于统计一个32位的二进制数值当中1的数量这个问题,常规解法如下:publicinthammingWeight(intn){intcount=0;for(inti=0;i<32;i++){n......
  • 【Java基础】String类 && StringBuilder类
    String类String类特点字符串底层是字节类型的数组:byte[]Java程序中所有双引号字符串,都是String类的实例(对象)字符串在创建之后,其内容不可更改字符串虽然不可以改变,但是可以被共享(通过字符串常量池)字符串常量池(StringTable)-->当使用双引号创建字符串对象时,会检查常量池中是......
  • 【Java基础】内存分配
    1.栈方法运行时所进入的内存2.堆需要new的引用数据类型会在堆内存中开辟空间并产生地址堆内存中的数据在生命周期结束后会由垃圾回收器不定时回收(C语言需要手动写代码清理释放内存空间)3.方法区字节码文件加载时进入的内存4.本地方法栈(辅助虚拟机)---了解5.寄存......
  • 二分查找图解
    二分查找图解使用二分查找的前提是所给的元素集合必须是单调的。整数二分查找最后一个小于等于q的元素的下标元素存在元素不存在查找第一个大于等于q的元素的下标元素存在元素不存在浮点数二分高效的牛顿法......
  • JavaWeb--JSP脚本
     JSP的缺点     ......
  • Java8新特性lambda学习
    Lambda表达式Lambda是一个匿名函数,我们可以把Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。使用它可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。本质:作为函数式接口的实例,没有接口就没意义了.//简单......
  • idea报错Java HotSpot(TM) 64-Bit Server VM warning Options -Xverifynone and -nove
    问题描述我的:IDEA的版本为:2021.3‍最近在使用idea运行SpringBoot时,idea总是显示报错信息,报错信息如下:‍​​‍解决方法‍第一步:选择下图的EditConfigurations‍​​‍第二步:在跳转出的界面中找到Modifyoptions这个选项,点进去‍​​‍第......