剑指Offer:二维数组中的查找(两种解法)

自闭症网瘾萝莉.ら 提交于 2020-03-07 00:02:34

剑指Offer:二维数组中的查找(两种解法)

  1. 问题描述

    在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
    示例: vector<vector > 【1, 2, 8, 9 】
    【2, 4, 9, 12】
    【4, 7, 10,13】
    【6, 11, 15,16】

2. 解题思路
解法1:利用二分查找以及该二维数组的特性
在示例中查询 6 ,执行的原理为:
①:先在第一行执行二分查找,
②:得到所需要查询的数介于vector[0][1]、vector[0][2]之间
③:接着查询第二行,但是第二行不做全部二分查找,由于所查询的数比vector[0][2],
所以所查询的数在vector[1][0]和vector[1][2]之间,以此减少运算,以下以此类推
解法2:利用该二维数组的特性
在示例中查询6,执行的步骤原理为:
①:首先我们需要确定一个以前,类似于走矩阵,此点的约束是:左下角或者右上角
原因:因为选择左下角或者右上角作为起点出发的话,可以根据该二维数组特性:拿右上角为例
如果查找的数比当前点小,则向左移动一个单位
如果查找的数比当前点大,则想下移动一个单位
②:从[9出发(6<9) 向左] -> [8(6<8) 向左] -> [2(6>2) 向下] -> [4(6>4)向下] -> [7(6<7)向左] -> [4(6>4)向下] -> [6]
③:直到向左,或者是向下超出范围,查找完毕。这种情况即时查找不到
④:最坏的情况就是,从(左下角->右上角)或者是(右上角->左下角)。时间复杂度最长,为o(m+n)

3.c++源码

解法1:

bool half_Find(int target, vector<vector<int> > array) 
{
				if(array.empty())
				{	
					return false;
				}else
				{
					if(array[0].empty())
					{
						return false;
					}
				}
        int len = array[0].size();
        int left = 0;
        int right = array[0].size() - 1;
        int index = 0;
        for(int i = 0;i < array.size();i++)
        {
            while(1)
            {
                index = (left + right)/2;
                if(target == array[i][index])
                {
                    return true;
                }
                else if(target > array[i][index])
                {
                    if(index == right)
                    {
                        left = index;
                        right = len -1;
                        break;
                    }
                    left = index + 1;
                }
                else if(target < array[i][index])
                {
                    if(index == left)
                    {
                        right = index;
                        left = 0;
                        break;
                    }
                    right = index -1;
                }
            }
        }
        return false;
}

解法2

bool Find(int target, vector<vector<int> > array)
{
	if(array.empty())
	{	
		return false;
	}else
	{
		if(array[0].empty())
		{
			return false;
		}
	}
	int index_y_max = array.size() - 1;
	int index_x_min = 0;
	
	int index_x = array[0].size() - 1;
	int index_y = 0;
	while(index_x >= index_x_min && index_y <=index_y_max)
	{
		if(target == array[index_y][index_x])
		{
			return true;	
		}
		if(target > array[index_y][index_x])
		{
			index_y++;
			continue;
		}
		else if(target < array[index_y][index_x])
		{
			index_x--;
			continue;
		}
	}
	return false;
}```

 

 
 **4. 留言**

CSDN:https://blog.csdn.net/qq_42714490
欢迎交流:
		##  	作者:有梦想的阿长
		## 	微信:hs835844948
【转载文章务必保留出处和署名,谢谢!】

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!