二维有序数组-二分查找(顺带一下快排)

二维数组中的查找

http://www.nowcoder.com/questionTerminal/abc3fe2ce8e146608e868a70efebf62e

public class Solution {
    public boolean Find(int target, int [][] array) {
        int m=array.length;
        if(m==0)return false;
        int n=array[0].length;
        if(n==0)return false;
        //右上角元素
        int r=0,c=n-1;
        while(r<m&&c>=0){
            if(array[r][c]>target){
                c--;
            }else if(array[r][c]<target){
                r++;
            }else{
                return true;
            }
        }
        return false;
    }
}

首先唠叨一下快排;
将数组A快排,low代表最低位,high代表最高位;
if(low<high)继续随机选取[low,high]之间的位置,将其与low位置的值对换,记录此时low的值为target;
然后在partition函数里面找到target的合适位置par[left,right],
[low,left]代表比target小的A的部分,[right+1,high]代表比target大的A的部分;
从low位置开始,left初始值为low-1,high初始值为high;
遇到和target大小相同的元素直接右移一位;
遇到比target小的元素将其与left+1位置的元素对换,并将left++;
遇到比target大的元素将其与right位置的值兑换一下,然后right--,然后进入重新判断环节,重复遇到三步;
partition函数后返回到快排函数,对区间[low,left]和[right+1,high]进行重新快排;
但是要小心一下low,left,right+1,high是否有哪些区间可以过滤掉;
简单的荷兰国旗问题,C++这么实现比C++提供的库函数要快,但是java还是调用java提供的库函数吧;

分析一下这个问题:
这个问题有一个条件:数组有有序特征,然后又是查找一类的问题,确定一个思路,二分查找;
二分查找是将值和数组中间值去比大小从而砍掉一半比较区间的思想,代价logn应该,这个还得计算一下,要用master公式计算一下;
这个问题的难点在于找到合适的中间值,中间值要有明确的比中间值大和比中间值小的范围,
又因为是二维数组,所以根据它的行和列自增的思想,这个范围最好是某行或某个列,观察来观察去,右上角的值或者左下角的值最合适做中间值,和他们比可以砍掉行或者列;
这里选择右上角;
接下来的问题就不是问题了;
直接看代码;
另外要注意所有数组都要判空;

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务