剑指offer之面试题4:二位数组中的查找

1、题目


2、解题思路

从左下角或者右上角开始比较,也可以采用二分查找

右上角查找过程如下:


3、Python 2.7.12版本实现(因为牛客网上为2.7版本)

3.1、自己写的(牛客网通过):暴力法

# -*- coding:utf-8 -*-
class Solution:
    # array 二维列表
    def Find(self, target, array):
        for i in range(len(array)):
            for j in range(len(array[0])):
                if target == array[i][j]:
                    return True
        return False

if __name__ == "__main__":
    array = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
    target = 19
    solution = Solution()
    is_exist = solution.Find(target,array)
    print is_exist

3.2、根据参考文献改进后的

# -*- coding:utf-8 -*-

'''
剑指offer之面试题4:二位数组中的查找

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

思路:
见程序标注

编程环境:
Python2.7.2

作者:
CSDN博客:https://my.csdn.net/yeqiang19910412
Github:https://github.com/YeQiang1075736553

日期:
2018.8.20
'''

class Solution:
    # array 二维列表
    def Find(self, target, array):
        """查找方式从左下角开始查找,每次比较都可以剔除一列或者一行,从而加快速度完成查找

        具体而言,假设选择的数字为 k,则有三种情况:
        1、target == k:此时直接返回即可
        2、target > k:剔除 k 所在的列(列号递增即可)
        3、target < k:剔除 k 所在的行(行号递减即可)

        参数:
        ----------
        :param target: int
            要查找的值
        :param array: [[]]
            二维数组

        返回值
        ----------
        :return: bool
            二维数组是否存在要查找的值

        示例
        ----------
        array = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
        target = 71
        solution = Solution()
        is_exist = solution.Find(target,array)
        print is_exist
        """
        # 如果数组为空
        if not array:
            return False

        num_row = len(array)
        num_col = len(array[0])

        # 左下角开始
        row = num_row-1
        col = 0
        while row >= 0 and col <= num_col-1:
            if target == array[row][col]:
                return True
            elif target > array[row][col]:
                col += 1
            else:
                row -= 1
        return False

###################################################################################################

'''
class Solution:
    # array 二维列表
    def Find(self, target, array):
        """查找方式从右上角开始查找,每次比较都可以剔除一列或者一行,从而加快速度完成查找

        具体而言,假设选择的数字为 k,则有三种情况:
        1、target == k:此时直接返回即可
        2、target > k:剔除 k 所在的行(行号递增即可)
        3、target < k:剔除 k 所在的列(列号递减即可)

        """
        # 如果数组为空
        if not array:
            return False

        num_row = len(array)
        num_col = len(array[0])

        # 右上角开始查找
        row = 0
        col = num_col-1
        while row <= num_row-1 and col >=0:
            if  target == array[row][col]:
                return True
            elif target > array[row][col]:
                row += 1
            else:
                col -= 1
        return False
'''

###################################################################################################

'''
class Solution:
    # array 二维列表
    def Find(self, target, array):
        """
        借助二分查找,可以在 O(nlogn) 的时间复杂度内完成查找
        """
        # 如果数组为空
        if not array:
            return False

        for row in array:
            if self.binary_search(row,target):
                return True

        return False

    def binary_search(self,seq,target):
        # 如果该行为空
        if not seq:
            return False

        low = 0
        high = len(seq)-1
        while low <= high:
            mid = low + (high - low)//2
            if seq[mid] > target:
                high = mid - 1
            elif seq[mid] < target:
                low =  mid + 1
            else:
                return True

        return False
'''

if __name__ == "__main__":
    array = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
    target = 7
    solution = Solution()
    is_exist = solution.Find(target,array)
    print is_exist

GitHub 代码地址 :GitHub 代码地址 t4.py

4、C++版本实现

#include"iostream"
#include"vector"
using namespace std;

/*************************************************
剑指offer之面试题4:二位数组中的查找

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

思路:
见程序标注

编程环境:
visual studio 2017

作者:
CSDN博客:https://my.csdn.net/yeqiang19910412
Github:https://github.com/YeQiang1075736553

日期:
2018.8.20
**************************************************/

//class Solution {
//public:
//  /**
//  * @brief 暴力解法
//  *
//  * @param target int 要查找的值
//  * @param array  vector<vector<int> > 二维数组
//  *
//  * @return bool 二维数组是否存在要查找的值
//  *
//  */
//  bool Find(int target, vector<vector<int> > array) {
//      if(array.empty()){
//          return false;
//      }
//      for (int i=0; i < array.size(); ++i) {
//          for (int j=0; j < array[i].size(); ++j) {
//              if(target == array[i][j]){
//                  return true;
//              }
//          }
//      }
//      return false;
//
//  }
//};

/////////////////////////////////////////////////////////////////////////////////////////////

//class Solution {
//public:
//  /**
//  * @brief 分治解-左下角
//  * 查找方式从左下角开始查找,每次比较都可以剔除一列或者一行,从而加快速度完成查找
//  *
//  * 具体而言,假设选择的数字为 k,则有三种情况:
//  * 1、target == k:此时直接返回即可
//  * 2、target > k:剔除 k 所在的列(列号递增即可)
//  * 3、target < k:剔除 k 所在的行(行号递减即可)
//  *
//  * @param target int 要查找的值
//  * @param array  vector<vector<int> > 二维数组
//  *
//  * @return bool 二维数组是否存在要查找的值
//  *
//  */
//  bool Find(int target, vector<vector<int> > array) {
//      if (array.empty()) {
//          return false;
//      }
//
//      int num_row = array.size();
//      int num_col = array[0].size();
//
//      int row = num_row - 1;
//      int col = 0;
//
//      while (row >= 0 && col <= num_col - 1) {
//          if (target == array[row][col]) {
//              return true;
//          }
//          else if (target > array[row][col]) {
//              ++col;
//          }
//          else {
//              --row;
//          }
//      }
//      return false;
//  }
//};

/////////////////////////////////////////////////////////////////////////////////////////////

//class Solution {
//public:
//  /**
//  * @brief 分治解-右上角
//  * 查找方式从右上角开始查找,每次比较都可以剔除一列或者一行,从而加快速度完成查找
//  *   
//  * 具体而言,假设选择的数字为 k,则有三种情况:
//  * 1、target == k:此时直接返回即可
//  * 2、target > k:剔除 k 所在的行(行号递增即可)
//  * 3、target < k:剔除 k 所在的列(列号递减即可)
//  *
//  * @param target int 要查找的值
//  * @param array  vector<vector<int> > 二维数组
//  *
//  * @return bool 二维数组是否存在要查找的值
//  *
//  */
//  bool Find(int target, vector<vector<int> > array) {
//      if(array.empty()){
//          return false;
//      }
//
//      int num_row = array.size();
//      int num_col = array[0].size();
//
//      int row = 0;
//      int col = num_col - 1;
//
//      while (row <= num_row-1 && col >= 0) {
//          if (target == array[row][col]) {
//              return true;
//          }
//          else if (target > array[row][col]) {
//              ++row;
//          }
//          else{
//              --col;
//          }
//      }
//      return false;
//  }
//};

/////////////////////////////////////////////////////////////////////////////////////////////

class Solution {
public:
    /**
    * @brief 分治解-二分法
    * 采用二分查找二维数组的每一行
    *
    * @param target int 要查找的值
    * @param array  vector<vector<int> > 二维数组
    *
    * @return bool 二维数组是否存在要查找的值
    *
    */
    bool Find(int target, vector<vector<int> > array) {
        if(array.empty()){
            return false;
        }

        int num_row = array.size();
        for (int i = 0; i < num_row; ++i) {
            if (binary_search(target,array[i])) {
                return true;
            }
        }
        return false;

    }

    bool binary_search(int target, vector<int> seq) {
        int low = 0;
        int high = seq.size()-1; 
        int mid = 0;
        while (low <= high) {
            mid = low + (high - low) / 2;
            if (seq[mid] > target) {
                high = mid - 1;
            }
            else if (seq[mid] < target) {
                low = mid + 1;
            }
            else {
                return true;
            }
        }
        return false;
    }
};

int main(void) {

    vector<vector<int> > arr = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };
    int target = 10;
    Solution solution;
    bool result = solution.Find(target, arr);
    cout << result << endl;
    system("pause");
    return 0;
}

GitHub 代码地址 :GitHub 代码地址 t4.cpp

参考文献:
1. Jack-Lee-Hiter/AlgorithmsByPython/Target Offer/二维数组查找.py:Python版本,右上角开始查找
2. JushuangQiao/Python-Offer/second/third/:Python版本,左下角开始查找
3. 0xE8551CCB/coding-interview-python/src/problems/p04_find_in_sorted_matrix.py:Python版本,右上角开始查找、左下角开始查找、二分查找
4. gatieme/CodingInterviews/003-二维数组中的查找/:C++版本
5. 剑指Offer(一):二维数组中的查找 :C++版本

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值