zoukankan      html  css  js  c++  java
  • 二维数组中的查找

    题目描述

    在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
    例如:下面的二维数组就是每行、每列都递增排序。如果在这个数组中查找数字7,则返回true;如果查找数字5,由于数组不含有该数字,则返回false。

    解题思路

    看到该题目想到的最简单暴力做的做法就是直接遍历数组查找。但是实际上一般都要用效率更高的做法,该题目有两个重要条件,从左到右递增,从上到下递增,也就是说每一个数都比前一个大比后一个小,比上面的大比下面的小。由此想到可以右上角或者左下角开始处理,这样每次处理都会剔除一行或者一列,逐渐缩小范围,直到找到要查找的数字或者没有。

    代码实现

    /// <summary>
    /// 检测是否在数组范围内
    /// </summary>
    /// <param name="array"></param>
    /// <param name="target"></param>
    /// <returns></returns>
    private static bool CheckIsArrayRange(int[,] array, int target)
    {
        bool result = false;
        if (array != null && array.Rank == 2)
        {
            int rowLength = array.GetLength(0);
            int colLength = array.GetLength(1);
            int start = array[0, 0];
            int end = array[rowLength - 1, colLength - 1];
            if (start <= target && target <= end)
            {
                result = true;
            }
        }
        return result;
    }
    
    /// <summary>
    /// 暴力解法-直接遍历
    /// </summary>
    /// <param name="array">数组</param>
    /// <param name="target">目标</param>
    /// <returns></returns>
    private static bool FindForSimple(int[,] array, int target)
    {
        bool result = false;
        if (CheckIsArrayRange(array, target))
        {
            foreach (var item in array)
            {
                if (target == item)
                {
                    result = true;
                    break;
                }
            }
        }
        return result;
    }
    
    /// <summary>
    /// 右上角解题
    /// </summary>
    /// <param name="array"></param>
    /// <param name="target"></param>
    /// <returns></returns>
    private static bool FindForRight(int[,] array, int target)
    {
        bool result = false;
    
        if (CheckIsArrayRange(array, target))
        {
            int rowLength = array.GetLength(0);
            int colLength = array.GetLength(1);
    
            int row = 0, col = colLength - 1;//坐标右上角
            while (row < rowLength && col >= 0)
            {
                if (array[row, col] == target)
                {
                    result = true;
                    break;
                }
                else if (array[row, col] > target)
                {
                    col--;
                }
                else
                {
                    row++;
                }
            }
        }
    
        return result;
    }

    想入非非:扩展思维,发挥想象

    目的:

    1. 熟悉二维数组

    2. 不要动不动就循环,多想想

    扩展:

    1. 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增n的顺序排序,每一列都按照从上到下递增n的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
    解题思路:从左到右递增n,从上到下递增n,这属于等比递增数组(自己起的),这样的如果还用右上角的做法,那效率不是很高,正确的做法是用等比数列计算求值的方法。(target-start)/n,如果可以整除,那么这个数据就存在,不能整除就不存在。

    代码实现

    /// <summary>
    /// 等比数列的数组
    /// </summary>
    /// <param name="array"></param>
    /// <param name="target"></param>
    /// <returns></returns>
    private static bool FindForN(int[,] array, int target)
    {
        bool result = false;
        if (CheckIsArrayRange(array, target))
        {
            int rowLength = array.GetLength(0);
            int colLength = array.GetLength(1);
            int first = array[0, 0];
            int second = 0;
    
            if (rowLength > 1) { second = array[1, 0]; }
            else if (colLength > 1) { second = array[0, 1]; }
            else { second = target; }
    
            int n = second - first;
            if (n == 0)
            {
                if (first == target)
                {
                    result = true;
                }
            }
            else
            {
                int remainder = (target - first) % n;
                if (remainder == 0)
                {
                    result = true;
                }
            }
        }
    
        return result;
    }

    2. 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数,有返回数据的坐标
    解题思路:按照右上角的解题思路,把坐标记录放到list中就可以了。

    测试

    [Fact]
    public void Test1()
    {
        int[,] array = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } };
        int target = 4;
        Assert.True(Coding001.FindForSimple(array, target));
        Assert.True(Coding001.FindForRight(array, target));
    }
    
    [Fact]
    public void Test3()
    {
        int[,] array = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } };
        int target = 3;
        Assert.False(Coding001.FindForSimple(array, target));
        Assert.False(Coding001.FindForRight(array, target));
    }
    
    [Fact]
    public void MinTest()
    {
        int[,] array = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } };
        int target = 0;
        Assert.False(Coding001.FindForSimple(array, target));
        Assert.False(Coding001.FindForRight(array, target));
    }
    
    
    [Fact]
    public void MaxText()
    {
        int[,] array = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } };
        int target = 16;
        Assert.False(Coding001.FindForSimple(array, target));
        Assert.False(Coding001.FindForRight(array, target));
    }
    
    [Fact]
    public void Test5()
    {
        int[,] array = { { 1, 2, 3, 4 }, { 2, 3, 4, 5 }, { 3, 4, 5, 6 } };
        int target = 3;
        Assert.True(Coding001.FindForSimple(array, target));
        Assert.True(Coding001.FindForRight(array, target));
        Assert.True(Coding001.FindForN(array, target));
    }
    
    [Fact]
    public void Test6()
    {
        int[,] array = { { 1, 2, 3, 4 }, { 2, 3, 4, 5 }, { 3, 4, 5, 6 } };
        int target = 7;
        Assert.False(Coding001.FindForSimple(array, target));
        Assert.False(Coding001.FindForRight(array, target));
        Assert.False(Coding001.FindForN(array, target));
    }
    
    [Fact]
    public void Test7()
    {
        int[,] array = { { 1, 3, 5, 7 }, { 3, 5, 7, 9 }, { 5, 7, 9, 11 } };
        int target = 9;
        Assert.True(Coding001.FindForSimple(array, target));
        Assert.True(Coding001.FindForRight(array, target));
        Assert.True(Coding001.FindForN(array, target));
    }
    
    [Fact]
    public void Test8()
    {
        int[,] array = { { 1, 3, 5, 7 }, { 3, 5, 7, 9 }, { 5, 7, 9, 11 } };
        int target = 8;
        Assert.False(Coding001.FindForSimple(array, target));
        Assert.False(Coding001.FindForRight(array, target));
        Assert.False(Coding001.FindForN(array, target));
    }
    View Code

    结果

  • 相关阅读:
    开放源码的对象关系映射工具ORM.NET 插入数据 Insert/Update Data
    开放源码的对象关系映射工具ORM.NET 快档开发入门 Quick Start
    .NET 动态脚本语言Script.NET 开发指南
    开放源码的对象关系映射工具ORM.NET 删除数据 Deleting Records using ORM.NET
    .NET Remoting过时了吗?为什么公司的项目还是选择用.NET Remoting,而不是WCF?
    开放源码的对象关系映射工具ORM.NET 查看和显示数据 View and Display data using ORM.NET
    开放源码的对象关系映射工具ORM.NET 查询表 调用存储过程 增加自定义代码
    技术人生:坚持,每日一博
    CQRS:CQRS + DDD + MDP 实现快速应用程序开发
    NodeJs:Happy代码生成器,重构了代码,更新了文档,完善了示例,欢迎下载使用
  • 原文地址:https://www.cnblogs.com/zhao123/p/11127262.html
Copyright © 2011-2022 走看看