找到连续1的最大数量

时间:2012-04-07 12:56:36

标签: algorithm matrix binary-search

  

给出2d矩阵,填充1和0。假设连续的所有1都在0之前。我们必须连续找到1的最大数量。

我已经提出了一个解决方案,我们可以在每一行上应用二进制搜索,以便在0开始之前得到该行中最后一个的最后一个索引,因此得到no。 1的将是它的指数+ 1。所以我们可以在每一行都这样做。 所以复杂性将是O(mlogn),其中m是no。行和n是否。列。 能有更好的解决方案吗?

7 个答案:

答案 0 :(得分:4)

可以在O(n + m)中完成。

以curmax等于0开始。

然后逐个处理行。增加curmax,同时该行中至少有curmax,即检查curmax值是否为1。

在处理完所有行后,答案将是curmax-th。

这适用于O(n + m)。

它会比O(m * logn)快吗?这取决于。如果m小于n /(log(n) - 1)它将起作用,实际上长于O(m * log n)并且更快,否则就复杂性而言。
在近似时间时考虑常数是另一个问题。所以对于一个数量级的n和m,这将更快,对于不同的只有一个选择 - 尝试两者,选择更好。

答案 1 :(得分:3)

您只对最大值感兴趣,因此您无需为每一行找到开关的位置。

找到第一行的开关位置k(0)后,从位置k(0)开始搜索第二行,如果是0,则第二行不包含最长的序列,所以你可以忽略它实际上的位置。这并没有改善最坏情况下的时间复杂度,但它会改善平均情况。

答案 2 :(得分:3)

O(n + m)算法的要点就是这个。

想象一下你的矩阵是一个网格。

从左上角开始。

如果你在1,向右移动。否则向下移动。

继续这样做,直到你通过最后一行。

然后你的x坐标是1的最大计数。

如果有一行全1,你可以移动一个经过最后一列。您的算法需要满足此要求。

答案 3 :(得分:1)

只需连续检查它,然后从您在上一行停止的位置开始下一行。如果为0,则转到下一行,否则继续检查该行。重复该过程直到最后一行。

答案 4 :(得分:1)

1     bool matrix[100][200];
2     int max = 0, count, x;
3     
4     for(int y=0;y<100;y++){
5         count = 0;
6         x=max; // This would optimize the search times!
7         for(;x<200;x++){
8             if(matrix[y][x] == 0 && count>max){
9                max=count;
10            }
11            else count++;
12        }
13        if(x == 199)break; // Optimization - the end reached
14    }
15
16    // Now the max var contains the maximum number of 1's of a single row in all columns.

您可以跳过已知的位置,而不是遍历每一行。 此优化在第6行上实施。

答案 5 :(得分:0)

在上面的代码中,似乎是第5行,即count = 0应该来自第一个循环,因为如果最大数量的1不在矩阵的第一行中,则错误地更新max变量。

我在下面写了正确的测试代码:

public static int findRowWithMax1s(int arr[][],int m, int n){

    int x,y,count=0,max=0;
    int row = 0;
    for(x=0;x<m;x++) {
        y = max;
        for(;y<n;y++) {
            if(arr[x][y] == 0) {
                max = count;
                row = x;
                break;
            }
            else
                count++;
        }
    }

    return max;
}

答案 6 :(得分:0)

#include <stdio.h>
#define R 4
#define C 4

/* A function to find the index of first index of 1 in a boolean array arr[] */
int first(bool arr[], int low, int high)
{
  if(high >= low)
  {
    // get the middle index  
    int mid = low + (high - low)/2; 

    // check if the element at middle index is first 1
    if ( ( mid == 0 || arr[mid-1] == 0) && arr[mid] == 1)
      return mid;

    // if the element is 0, recur for right side
    else if (arr[mid] == 0)
      return first(arr, (mid + 1), high);

    else // If element is not first 1, recur for left side
      return first(arr, low, (mid -1));
  }
  return -1;
}

// The main function that returns index of row with maximum number of 1s. 
int rowWithMax1s(bool mat[R][C])
{
    int max_row_index = 0, max = -1; // Initialize max values

    // Traverse for each row and count number of 1s by finding the index 
    // of first 1
    int i, index;
    for (i = 0; i < R; i++)
    {
       index = first (mat[i], 0, C-1);
       if (index != -1 && C-index > max)
       {
           max = C - index;
           max_row_index = i;
       }
    }

    return max_row_index;
}

/* Driver program to test above functions */
int main()
{
    bool mat[R][C] = { {0, 0, 0, 1},
        {0, 1, 1, 1},
        {1, 1, 1, 1},
        {0, 0, 0, 0}
    };

    printf("Index of row with maximum 1s is %d n", rowWithMax1s(mat));

    return 0;
}