• 面试题3-二维数组中的查找


    面试题3-二维数组中的查找

    基础知识

    数组是最简单的一种数据结构,它占据一块连续的内存并按照顺序存储数据。在创建数组的时候,必须首先指定数组的容量大小,然后根据大小来分配内存,一经建立之后数组的大小便不能更改,这就造成了其空间利用的效率不够高。但是数组的内存是连续的,可以根据下标在O(1)的时间内读写任意的元素,因此它的时间效率很高。
    在不同的编程语言中,都存在动态数组,如C++中的Vector,Java中的ArrayList。这些动态数组都有初始容量,当数据的数目超过数组的初始容量的时候,重新分配一块更大的空间,把之前的数据复制到新的数组中去,释放之前的内存,这样减少了内存的浪费。但是每一次的扩容都会有大量的额外操作,这会对时间性能造成影响,因此在使用动态数组的时候要尽量减少改变数组容量的次数。

    题目

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

    解题思路:

    1. 这道题暴力的解法是两层的循环逐一的查找,显然这种复杂度O(mn)的算法是不可取的。
    2. 可以在此基础之上进行改进,每一行使用二分查找的方法,减少查找的次数,那么复杂度就能下降到O(mlgn)。
    3. 首先比较二维数组右上角的数字,若和目标数据相等,查找结束,如果该数字大于要查找的数字,则剔除这个数字所在的列;如果该数字小于要查找的数字,则剔除该数字所在的行。这样一行一列的逐步缩小要查找的范围,最后找到数字或者范围为空。(仔细想想这种解法有点动归的意思)这种思想的算法复杂度最坏情况下为O(m+n)。算法还是很神奇的。

    代码

    二分:

    1. public class Solution
    2. public boolean Find(int target, int [][] array)
    3. if( array == null
    4. return false
    5.  
    6. int row = array.length; 
    7. //System.out.println(row); 
    8. int col = array[0].length; 
    9. boolean res = false
    10. if(row > 0 && col >0){ 
    11. int min = array[0][0]; 
    12. int max = array[row-1][col-1]; 
    13. if(target < min || target > max) 
    14. return false
    15. //System.out.println("test"); 
    16. int i = 0
    17.  
    18. while( i < col){ 
    19. int low = 0,high = row - 1, mid = 0
    20. while(low <= high){ 
    21. mid = low + (high - low)/2
    22. if(target == array[i][mid]){ 
    23. res = true
    24. return res; 

    25. if(target > array[i][mid]){ 
    26. low = mid + 1
    27. }else
    28. high = mid - 1


    29. i ++; 


    30. return res; 
    31.  


    从右上删减行列减少范围:

    1. public class Solution
    2. public boolean Find(int target, int [][] array)
    3. int row = array.length; 
    4. if(row == 0
    5. return false
    6. int col = array[0].length; 
    7. int i = 0, j = col - 1
    8. while(i < row && j >=0 ){ 
    9. if(target == array[i][j]) 
    10. return true
    11. if(target > array[i][j]) 
    12. i++; 
    13. else 
    14. j--; 

    15. return false


  • 相关阅读:
    2017区块链七大趋势,概念热炒之后行业如何发展?
    区块链三大方向:比特币,其他公有链和区块链联盟,以及私有链。
    这条消息被许多人忽视,但对房价可能“一剑封喉”!
    世界主要城市名称中英文对照
    2016全球城市竞争力排行榜
    全球城市群Megalopolis
    gawc全球城市
    2016全球资产配置白皮书(附下载)
    160. Intersection of Two Linked Lists
    save change is not permitted
  • 原文地址:https://www.cnblogs.com/chailinbo/p/8401446.html
Copyright © 2020-2023  润新知