Дан логический 2D-массив, в котором отсортирована каждая строка. Найдите строку с максимальным количеством 1 с.
Пример:
Input matrix
0 1 1 1
0 0 1 1
1 1 1 1 // this row has maximum 1s
0 0 0 0
Output: 2
Простой метод состоит в том, чтобы выполнить пошаговый обход матрицы, посчитать количество единиц в каждой строке и сравнить число с макс. Наконец, верните индекс строки с максимумом 1 с. Временная сложность этого метода составляет O (m * n), где m — количество строк, а n — количество столбцов в матрице.
Мы можем сделать лучше. Поскольку каждая строка отсортирована, мы можем использовать двоичный поиск для подсчета 1 с в каждой строке. Мы находим индекс первого экземпляра 1 в каждой строке. Количество 1 с будет равно общему количеству столбцов минус индекс первого 1.
См. Следующий код для реализации вышеупомянутого подхода.
C ++
#include <bits/stdc++.h>
using namespace std;
#define R 4 #define C 4
int first( bool arr[], int low, int high)
{
if (high >= low)
{
int mid = low + (high - low)/2;
if ( ( mid == 0 || arr[mid-1] == 0) && arr[mid] == 1)
return mid;
else if (arr[mid] == 0)
return first(arr, (mid + 1), high);
else
return first(arr, low, (mid -1));
}
return -1;
}
int rowWithMax1s( bool mat[R][C])
{
int max_row_index = 0, max = -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;
}
int main()
{
bool mat[R][C] = { {0, 0, 0, 1},
{0, 1, 1, 1},
{1, 1, 1, 1},
{0, 0, 0, 0}};
cout << "Index of row with maximum 1s is " << rowWithMax1s(mat);
return 0;
}
|
С
#include <stdio.h> #define R 4 #define C 4
int first( bool arr[], int low, int high)
{
if (high >= low)
{
int mid = low + (high - low)/2;
if ( ( mid == 0 || arr[mid-1] == 0) && arr[mid] == 1)
return mid;
else if (arr[mid] == 0)
return first(arr, (mid + 1), high);
else
return first(arr, low, (mid -1));
}
return -1;
}
int rowWithMax1s( bool mat[R][C])
{
int max_row_index = 0, max = -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;
}
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 "
, rowWithMax1s(mat));
return 0;
}
|
Джава
import java.io.*;
class GFG {
static int R = 4 , C = 4 ;
static int first( int arr[], int low, int high)
{
if (high >= low) {
int mid = low + (high - low) / 2 ;
if ((mid == 0 || (arr[mid - 1 ] == 0 )) && arr[mid] == 1 )
return mid;
else if (arr[mid] == 0 )
return first(arr, (mid + 1 ), high);
else
return first(arr, low, (mid - 1 ));
}
return - 1 ;
}
static int rowWithMax1s( int mat[][])
{
int max_row_index = 0 , max = - 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;
}
public static void main(String[] args)
{
int mat[][] = { { 0 , 0 , 0 , 1 },
{ 0 , 1 , 1 , 1 },
{ 1 , 1 , 1 , 1 },
{ 0 , 0 , 0 , 0 } };
System.out.println( "Index of row with maximum 1s is "
+ rowWithMax1s(mat));
}
}
|
Python 3
def first( arr, low, high):
if high > = low:
mid = low + (high - low) / / 2
if (mid = = 0 or arr[mid - 1 ] = = 0 ) and arr[mid] = = 1 :
return mid
elif arr[mid] = = 0 :
return first(arr, (mid + 1 ), high)
else :
return first(arr, low, (mid - 1 ))
return - 1
def rowWithMax1s( mat):
R = len (mat)
C = len (mat[ 0 ])
max_row_index = 0
max = - 1
for i in range ( 0 , R):
index = first (mat[i], 0 , C - 1 )
if index ! = - 1 and C - index > max :
max = C - index
max_row_index = i
return max_row_index
mat = [[ 0 , 0 , 0 , 1 ],
[ 0 , 1 , 1 , 1 ],
[ 1 , 1 , 1 , 1 ],
[ 0 , 0 , 0 , 0 ]]
print ( "Index of row with maximum 1s is" ,
rowWithMax1s(mat))
|
C #
using System;
class GFG
{
public static int R = 4, C = 4;
public static int first( int [] arr,
int low, int high)
{
if (high >= low)
{
int mid = low + (high - low) / 2;
if ((mid == 0 || (arr[mid - 1] == 0)) &&
arr[mid] == 1)
{
return mid;
}
else if (arr[mid] == 0)
{
return first(arr, (mid + 1), high);
}
else
{
return first(arr, low, (mid - 1));
}
}
return -1;
}
public static int rowWithMax1s( int [][] mat)
{
int max_row_index = 0, max = -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;
}
public static void Main( string [] args)
{
int [][] mat = new int [][]
{
new int [] {0, 0, 0, 1},
new int [] {0, 1, 1, 1},
new int [] {1, 1, 1, 1},
new int [] {0, 0, 0, 0}
};
Console.WriteLine( "Index of row with maximum 1s is " +
rowWithMax1s(mat));
} }
|
PHP
<?php
define( "R" , 4);
define( "C" , 4);
function first( $arr , $low , $high )
{
if ( $high >= $low )
{
$mid = $low + intval (( $high - $low ) / 2);
if (( $mid == 0 || $arr [ $mid - 1] == 0) &&
$arr [ $mid ] == 1)
return $mid ;
else if ( $arr [ $mid ] == 0)
return first( $arr , ( $mid + 1), $high );
else
return first( $arr , $low , ( $mid - 1));
}
return -1;
}
function rowWithMax1s( $mat )
{
$max_row_index = 0;
$max = -1;
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 ;
}
$mat = array ( array (0, 0, 0, 1),
array (0, 1, 1, 1),
array (1, 1, 1, 1),
array (0, 0, 0, 0));
echo "Index of row with maximum 1s is " .
rowWithMax1s( $mat );
?>
|
Выход:
Index of row with maximum 1s is 2
Сложность времени: O (mLogn), где m — количество строк, а n — количество столбцов в матрице.
Вышеуказанное решение может быть дополнительно оптимизировано . Вместо того, чтобы выполнять бинарный поиск в каждой строке, мы сначала проверяем, имеет ли строка больше 1 с, чем макс. Если в строке больше 1, то считайте только 1 в строке. Кроме того, чтобы посчитать 1 с в строке, мы не выполняем бинарный поиск в полной строке, мы выполняем поиск до индекса последнего максимума.
Ниже приведена оптимизированная версия вышеуказанного решения.
C ++
#include <bits/stdc++.h>
using namespace std;
int rowWithMax1s( bool mat[R][C])
{
int i, index;
int max_row_index = 0;
int max = first(mat[0], 0, C - 1);
for (i = 1; i < R; i++)
{
if (max != -1 && mat[i][C - max - 1] == 1)
{
index = first (mat[i], 0, C - max);
if (index != -1 && C - index > max)
{
max = C - index;
max_row_index = i;
}
}
else
{
max = first(mat[i], 0, C - 1);
}
}
return max_row_index;
}
|
С
int rowWithMax1s( bool mat[R][C])
{
int i, index;
int max_row_index = 0;
int max = first(mat[0], 0, C-1);
for (i = 1; i < R; i++)
{
if (max != -1 && mat[i][C-max-1] == 1)
{
index = first (mat[i], 0, C-max);
if (index != -1 && C-index > max)
{
max = C - index;
max_row_index = i;
}
}
else {
max = first(mat[i], 0, C - 1);
}
}
return max_row_index;
}
|
Наихудшая временная сложность оптимизированной версии выше также равна O (mLogn), решение в среднем будет работать лучше. Спасибо Навину Кумар Сингху за предложенное выше решение.
Наихудший случай вышеуказанного решения имеет место для матрицы, подобной следующей.
0 0 0… 0 1
0 0 0 ..0 1 1
0… 0 1 1 1
… .0 1 1 1 1
Следующий метод работает в O (m + n) временной сложности в худшем случае .
Шаг 1: Получить индекс первой (или самой левой) 1 в первом ряду.
Шаг 2: Делайте следующее для каждого ряда после первого ряда
… Если элемент слева от предыдущего левого 1 равен 0, игнорировать эту строку.
… В противном случае двигаться влево, пока не будет найден 0. Обновите крайний левый индекс до этого индекса, а max_row_index будет текущей строкой.
Сложность по времени составляет O (m + n), потому что мы, возможно, можем пойти так далеко налево, как мы продвинулись на первом шаге.
Ниже приведена реализация этого метода на C ++.
int rowWithMax1s( bool mat[R][C])
{
int max_row_index = 0;
int j = first(mat[0], 0, C-1);
if (j == -1)
j = C - 1;
for ( int i = 1; i < R; i++)
{
while (j >= 0 && mat[i][j] == 1)
{
j = j-1;
max_row_index = i;
}
}
return max_row_index;
}
|
Спасибо Tylor, Ankan и Palash за их вклад.
Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.
Рекомендуемые посты:
Найти строку с максимальным количеством 1 с
0.00 (0%) 0 votes