面试练习题汇总
  • 说明
  • C/C++ 问答题汇总
  • 编程题汇总
    • 腾讯 2017 暑期实习生编程题
      • 构造回文
      • 算法基础-字符移位
      • 有趣的数字
    • 剑指 Offer 编程题练习
      • 二维数组中的查找
      • 从尾到头打印链表
      • 旋转数组的最小数字
      • 替换空格
      • 用两个栈实现队列
      • 重建二叉树
    • 网易 2017 校招笔试编程题
      • 二进制权重
      • 平方串
      • 数位和
  • 安全测试开发相关面试
    • 安全测试类面试参考
    • 业务安全类面试参考
    • 测试开发类面试参考
  • 深信服sangfor相关
    • 深信服acm相关
    • 测试类面试参考
    • 智安全杯
      • 智安全杯-2018比赛
      • 智安全杯-2019初赛
      • 智安全杯-2019复赛
  • 软件测试题汇总
  • 计算机知识题汇总
    • 前 75 题
    • 75 题以后
  • Python 语言特性
    • 1 Python的函数参数传递
    • 2 @staticmethod和@classmethod
    • 3 类变量和实例变量
    • 4 Python中单下划线和双下划线
    • 5 args and *kwargs
    • 6 面向切面编程AOP和装饰器
    • 7 单例模式
    • 8 Python 函数式编程
    • 9 Python 里的拷贝
  • stackoverflow-about-Python
    • Python中关键字yield有什么作用?
    • [Python中的元类(metaclass)是什么?](stackoverflow-about-Python/Python中的元类(metaclass)是什么.md)
    • Python中如何在一个函数中加入多个装饰器?
    • 如何判断一个文件是否存在?
    • 如何调用外部命令?
    • 枚举类型的使用?
    • 在Windows下安装pip?
    • 字典合并问题
    • 在Android上运行Python
    • 根据字典值进行排序
    • 在函数里使用全局变量
    • 变化的默认参数
    • 装饰器classmethod和staticmethod的区别
    • 检查列表为空的最好办法
    • 怎么用引用来改变一个变量
    • 检查文件夹是否存在的操作
    • name=main的作用
    • super与init方法
    • str与repr的区别
    • 循环中获取索引
    • 类里的静态变量
    • 怎么在终端里输出颜色?
    • 为什么用pip比用easy_install的好?
    • join的问题
    • 把列表分割成同样大小的块
    • 为什么代码在一个函数里运行的更快
    • 如何快速合并列表中的列表?
    • 如何知道一个对象有一个特定的属性?
    • 如何通过函数名的字符串来调用这个函数?
    • 单下划线和双下划线的含义?
  • Python 面试编程题
    • 1 台阶问题 斐波那契
    • 2 变态台阶问题
    • 3 矩形覆盖
    • 4 杨氏矩阵查找
    • 5 去除列表中的重复元素
    • 6 链表成对调换
    • 7 创建字典的方法
    • 8 合并两个有序列表
    • 9 二分查找
    • 10 快排
    • 11 找零问题
    • 12 二叉树相关
    • 13 单链表逆置
Powered by GitBook
On this page
  • 题目
  • 思路
  • rectangle_search.py
  • 单元测试

Was this helpful?

  1. Python 面试编程题

4 杨氏矩阵查找

题目

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

思路

  • 参考: 剑指 Offer (面试题 3)

  • 总结查找的过程,发现规律如下:

    • 首先选取数组中右上角的数字。如果该数字等于要查找的数字,查找过程结束;

    • 如果该数字大于要查找的数字,剔除这个数字所在的列;

    • 如果该数字小于要查找的数字,剔除这个数字所在的行。

    • 也就是说如果要查找的数字不在数组的右上角,则每一次都在数组的查找范围中剔除一行或者一列,这样每一步都可以缩小查找的范围,

    • 直到找到要查找的数字,或者查找范围为空。

rectangle_search.py

#!/bin/env python3
# -*- coding: utf-8 -*-
# version: Python3.X

import timeit
import random

__author__ = '__L1n__w@tch'


def python_style_solve(a_list, number_to_find):
    """
    用 Python 的风格解决, 思路是把二维数组转换为一维数组, 然后执行查找
    :param a_list: 要查找的二维数组
    :param number_to_find: 待查找的数字
    :return: True or False
    """
    sum_list = list()
    for each in a_list:
        sum_list.extend(each)
    if number_to_find in sum_list:
        return True
        # print("Found!")


def c_style_solve(a_list, rows, columns, number_to_find):
    """
    用 C 的风格解决, 思路参考剑指 Offer
    :param a_list: 要查找的二维数组
    :param rows: 行
    :param columns: 列
    :param number_to_find: 待查找的数字
    :return: True or False
    """
    found = False

    if a_list is not None and rows > 0 and columns > 0:
        row, column = 0, columns - 1
        while row < rows and column >= 0:
            if a_list[row][column] == number_to_find:
                found = True
                break
            elif a_list[row][column] > number_to_find:
                column -= 1
            else:
                row += 1
    return found


if __name__ == "__main__":
    python_time = list()
    c_time = list()

    for i in range(30):
        number = random.choice([i for i in range(9)])
        print("第 {} 次, 查找数字: {}".format(i + 1, number))

        test_list = [[i for i in range(3)], [i for i in range(3, 6)], [i for i in range(6, 9)]]
        time_cost = timeit.timeit("python_style_solve(test_list, {})".format(number),
                                  setup="from __main__ import python_style_solve, test_list")
        print("Python 风格执行时间: {} s".format(time_cost))
        python_time.append(time_cost)

        time_cost = timeit.timeit("c_style_solve(test_list, len(test_list), len(test_list[0]), {})".format(number),
                                  setup="from __main__ import c_style_solve, test_list")
        print("C 风格执行时间: {} s".format(time_cost))
        c_time.append(time_cost)

    print("Python 平均时间: {}, C 平均时间: {}".format(sum(python_time) / len(python_time), sum(c_time) / len(c_time)))

单元测试

#!/bin/env python3
# -*- coding: utf-8 -*-
# version: Python3.X
""" 对杨氏矩阵查找的几种解法进行单元测试
"""
import unittest
from rectangle_search import python_style_solve, c_style_solve

__author__ = '__L1n__w@tch'


class TestAnswer(unittest.TestCase):
    def setUp(self):
        self.repeat_list = [[1, 2, 8, 9], [2, 4, 9, 12], [4, 7, 10, 13], [6, 8, 11, 15]]
        self.no_repeat_list = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16], [17, 18, 19, 20]]

    def test_normal(self):
        # 测试数字在其中的情况
        wait_to_search = [1, 9, 2, 12, 4, 13, 6, 15, 11, 8, 10, 7, 9, 4, 8, 2]
        print("二维数组: ".format(self.repeat_list))
        for each_number in wait_to_search:
            print("测试查找数字: {}".format(each_number))
            self.failUnless(python_style_solve(self.repeat_list, each_number))
            self.failUnless(
                c_style_solve(self.repeat_list, len(self.repeat_list), len(self.repeat_list[0]), each_number))

            # 测试数字不在其中的情况
            # self.failIf()


if __name__ == "__main__":
    pass
Previous3 矩形覆盖Next5 去除列表中的重复元素

Last updated 5 years ago

Was this helpful?