Java 二维数组中最小化读取次数的算法

Java 二维数组中最小化读取次数的算法,java,algorithm,Java,Algorithm,给定一个大小为x*y,数字范围为1到x*y的二维数组,或具有以下条件的null数组- m[x,y]==null|| m[x,y]>m[x',y']其中(x>x'&&y=y')||(y>y')) 例如: 2X2 array: 4 0 0 0 2X2 array: 3 0 0 4 编写一个算法,以最小读取次数输出1到x*y之间缺失的数字列表 分配一个大小为(x*y)的初始化为false的布尔数组 检查矩阵中的所有单元格,并将数组(M(x,y))设置为true 检查数组并打印所有索引,其中数组

给定一个大小为x*y,数字范围为1到x*y的二维数组,或具有以下条件的null数组- m[x,y]==null|| m[x,y]>m[x',y']其中(x>x'&&y=y')||(y>y'))

例如:

2X2 array: 
4 0
0 0

2X2 array: 
3 0
0 4

编写一个算法,以最小读取次数输出1到x*y之间缺失的数字列表

分配一个大小为(x*y)的初始化为false的布尔数组

检查矩阵中的所有单元格,并将数组(M(x,y))设置为true

检查数组并打印所有索引,其中数组(i)=false


如果您正在寻找一个技巧,缺失数字的总和(1到(x*y)的总和-矩阵的总和)和缺失数字的数量可能足以确定它们是什么。其主要思想是,根据问题的定义,一行中的最小值是您可以期望在前一行中找到的最大值。(相同的想法是,在一行中找到的最大值是在下一行中可以预期的最小值)。如果您找到了一行的最大值(或最小值),您就不必继续访问矩阵,因为没有任何意义,这样您就可以节省大量步骤,从而成为最佳解决方案

static List<int> Missing(int[,] matrix, int x, int y)
{
    bool[] numbers = new bool[x * y + 1]; //All values found in the matrix
    int max = x * y; //Max possible value in a row
    int min = max; //Min possible value in a row
    int row = y - 1; //Starting from the last row in the matrix until the first one
    while ((row >= 0) && (min > 1)) //Stop accessing in case that the global possible minimum (value 1) is found in a row greater than first one
    {
        int col = -1;
        do
        {
            col++;
            if (matrix[row, col] > 0) //Assuming that value 0 means null
            {
                numbers[matrix[row, col]] = true; //Mark as found the value in the cell
                min = Math.Min(min, matrix[row, col]); //Update the minimun value of the row (first non zero value in the row)
            }
        }
        while ((col < x - 1) && (matrix[row, col] < max) && (min > 1)); //Inside the matrix range? Stop condition to do not access more elements in that row
        max = min - 1; //Update the possible maximum value for the following row (row - 1)
        row--;
    }
    var result = new List<int>();
    for (var index = 1; index <= x * y; index++)
        if (!numbers[index]) //Return only those values that were NOT found in the matrix
            result.Add(index);
    return result;
}
缺少静态列表(int[,]矩阵,int x,int y)
{
bool[]number=new bool[x*y+1];//在矩阵中找到的所有值
int max=x*y;//行中的最大可能值
int min=max;//行中可能的最小值
int row=y-1;//从矩阵中的最后一行开始,直到第一行
while((row>=0)&&(min>1))//如果在大于第一行的行中找到全局可能最小值(值1),则停止访问
{
int col=-1;
做
{
col++;
if(matrix[row,col]>0)//假设值0表示null
{
numbers[matrix[row,col]]=true;//将单元格中的值标记为找到的值
min=Math.min(min,matrix[row,col]);//更新行的最小值(行中的第一个非零值)
}
}
而((列1));//在矩阵范围内?停止条件以不访问该行中的更多元素
max=min-1;//更新下一行(第1行)可能的最大值
行--;
}
var result=新列表();
对于(变量索引=1;索引0?数字[numbers.Count-1]。ToString():string.Empty);

希望它能解决您的问题。

这看起来像是家庭作业,如果是,请添加家庭作业标签。这不是家庭作业,我在访谈中提出的问题之一。如果您发布您到目前为止尝试过的内容,这会有所帮助。此外,这个问题是用java实现的吗?我看到了java标签,但问题中没有java特定的内容。我猜输出是示例的ts是[1,2,3]和[1,2]。读取的次数是多少?我猜是1和4@BharatSinha,这是OP添加家庭作业标签的任务,而不是我们。您没有指定阅读的目标数量。“减少”目标是避免读取所有单元格。我们需要使用条件跳过读取某些单元格。如果从右下角扫描矩阵,首先向上,然后向左。任何非零值都意味着矩阵中所有尚未扫描的值都低于当前值(所以它实际上是排序的,有缺失的数字)算法是不正确的,考虑4x1矩阵<代码> { 1, 2, 4,0 } <代码> @荒谬的想法,对不起,但是算法本身是正确的,错误的部分在使用代码示例中,因为我改变了索引顺序,而不是调用:列表号=缺失(矩阵,矩阵.GETFACE(0))。,matrix.GetLength(1));我们应该调用:List number=Missing(matrix,matrix.GetLength(1),matrix.GetLength(0));现在它输出了正确的答案。感谢您的建议。我修改了代码以包含更多优化。如果我们在任何一行中发现值1,则没有必要继续循环较低的行并保存大量访问。
int[,] matrix =
{
    { 0,  2,  0, 11, 0 },
    { 0,  0,  0,  0, 0 },
    { 0, 12,  0, 15, 0 },
    { 0, 16,  0,  0, 0 },
    { 0,  0, 21, 25, 0 }
};
List<int> numbers = Missing(matrix, matrix.GetLength(0), matrix.GetLength(1));
for (int index = 0; index < numbers.Count - 1; index++)
    Console.Write(numbers[index].ToString() + " ");
Console.WriteLine(numbers.Count > 0 ? numbers[numbers.Count - 1].ToString() : string.Empty);