• 二维数组的查找、旋转数组的最小数字


    📌导航小助手📌

          📖前面的话📖

               🔒题目一:二维数组中的查找🔒

                       🔐题目描述🔐

                       💡解题思路

                       🔑源代码

                       🖋总结🖋

               🔒题目二:旋转数组的最小数字🔒

                       🔐题目描述🔐

                       💡解题思路

                       🔑源代码

                       ​​​​​​​🖋总结🖋


     

     

    📖前面的话📖

    本专栏介绍的是 牛客网 上面的两道题解,同时 解题所用语言均为 Java语言 ~

    牛客网链接:🚘牛客网直通车🚘

    🔒题目一:二维数组中的查找🔒

    ✨题目链接:二维数组中的查找

     

    🔐题目描述🔐

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

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

    给定 target = 7,返回 true。

    给定 target = 3,返回 false。


    示例1:

    1. 输入:7,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
    2. 返回值:true
    3. 说明:存在7,返回true

    示例2:

    1. 输入:1,[[2]]
    2. 返回值:false

     示例3:

    1. 输入:3,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
    2. 返回值:false
    3. 说明:不存在3,返回false

    💡解题思路

    思路一:

    遍历二维数组,在期间进行判断,如果找到目标值,返回 true,如果找不到目标值,返回 false ~

    缺点:效率低下 ~


    思路二:

    通过每一次查找,都会排除多个元素; 

    通过观察,我们可以发现,每一行的最右上角的元素 都是该行的最大值,都是该列的最小值 ~

    以所给的描述中的二维数组为例,假设此时所要查找的目标值是 7,那么,此时要比最右上角的值9 要小,就说明 目标值肯定不在该列(因为该列的最小值就是 最右上角的值9,目标值比这一列最小的值还要小),那么 此时就可以排除这一列的值了 ~

    同样的道理,如果目标值要比最右上角的值还要大,就说明目标值就不再这一行,这样就直接排除了一行的值 ~

    此时,此时查找的效率就相对于比较高了 ~

    这种思路要考虑一下临界条件 !!!

    🔑源代码

    1. public class Solution {
    2. //二维数组的查找
    3. public boolean Find(int target, int [][] array) {
    4. //判断二维数组为null 或者 数组长度为 0 (非法情况)
    5. if(array == null || array.length == 0){
    6. return false;
    7. }
    8. //i、j表示的是数组的下标
    9. //i表示行,j表示列
    10. int i = 0;
    11. int j = array[0].length - 1;
    12. while (i<array.length && j>=0){
    13. //目标值大于最右边的值
    14. if(target > array[i][j]) {
    15. //不可能出现在这一行
    16. i++;
    17. }
    18. else if(target < array[i][j]) {
    19. j--;
    20. }
    21. else {
    22. return true;
    23. }
    24. }
    25. return false;
    26. }
    27. }

    🖋总结🖋

    • 需要注意的是 非法的情况:一是数组为 null,二是数组长度为 0;
    • 需要注意的是 二维数组中,第一行的长度可以用 array[0].length 来表示 ~

    🔒题目二:旋转数组的最小数字🔒

    ✨题目链接:旋转数组的最小数字

    🔐题目描述🔐

    有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这样一个旋转数组,求数组中的最小值。

    要求:空间复杂度:O(1),时间复杂度:O(logn) 。

    示例1:

    1. 输入:[3,4,5,1,2]
    2. 返回值:1

     示例2:

    1. 输入:[3,100,200,3]
    2. 返回值:3

     

    💡解题思路

    思路一:

    遍历整个数组,遍历期间,定义一个最小值,如果数组中的哪个元素要比最小值还要小,自动更新 ~

    思路二:

    由于数组非递减,而且是旋转过来的;

    [1,2,3,4,5] --> [4,5,1,2,3]

    所以可以比较 当前值和下一个值的大小,如果当前值 <= 下一个值,那么就是正确的,可以换下一个;如果当前值 >= 下一个值的大小(第一次大于),那么就说明 下一个值就是我们要找的最小元素 ~

    思路三: 

    不管怎么旋转数组,得到的数组都可以把它看成两个 "非递减的" 部分,只是由于旋转次数的不同,最小值时在中间值的左边或右边或正好就是中间值罢了;

    同时,前半部分的值 要在整体上 > 后半部分的值 ;

    🔑源代码

    1. import java.util.*;
    2. import java.util.ArrayList;
    3. public class Solution {
    4. public int minNumberInRotateArray(int [] array) {
    5. //合法性判断
    6. if (array == null || array.length == 0) {
    7. return 0;
    8. }
    9. int left = 0;
    10. int right = array.length - 1;
    11. int mid = 0;
    12. while(array[left] >= array[right]) {
    13. //如果两个元素已经相邻了,说明最右侧的值一定是要找的值
    14. if(right - left == 1) {
    15. mid = right;
    16. break;
    17. }
    18. //左边值 == 中间值 == 右边值 的情况
    19. if(array[left] == array[right] && array[left] == array[mid]) {
    20. int result = array[left];
    21. //一个一个遍历
    22. for (int i = left + 1; i < right; i++) {
    23. if(result > array[i]) {
    24. result = array[i];
    25. }
    26. }
    27. return result;
    28. }
    29. //更新 mid 的值
    30. mid = (right + left) >> 1;
    31. //如果中间值 >= 左半部分的值,就说明 最小的值在右半部分,这就直接把左半部分的值给排除了
    32. if(array[mid] >= array[left]) {
    33. left = mid;
    34. }
    35. else {
    36. right = mid;
    37. }
    38. }
    39. return array[mid];
    40. }
    41. }

    🖋总结🖋

    • 该题仍然是查找类型的题目,如果一次可以排除多个元素显然是更好
    • 在使用二分查找的时候,需要另起判断 是否左中右值相等的情况

    这篇博客就写到这里啦 ~

    如果觉得写得不错的老铁们,一键三连起来吧 ~

  • 相关阅读:
    安全测试专家强烈推荐的13款免费的测试工具
    绘图系统三:支持散点图、极坐标和子图绘制
    SpringBoot项目中使用MybatisPlus
    Python 网络爬虫:深入解析 Scrapy
    基于低代码平台开发的督办系统为企业管理赋能
    Sklearn基本算法
    《动手学深度学习 Pytorch版》 6.1 从全连接层到卷积
    编程软件大全(下载+安装+破解)
    Ubuntu/Debian/CentOS搭建Socks5代理一键脚本
    JS获取经纬度, 并根据经纬度得到城市信息
  • 原文地址:https://blog.csdn.net/qq_53362595/article/details/126797032