查找 1 最多的行
原文: https://www.geeksforgeeks.org/find-the-row-with-maximum-number-1s/
给定一个布尔 2D 数组,其中对每一行进行排序。 查找 1s 最多的行。
示例:
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 的数量,然后将其与最大值进行比较。 最后,返回最大为 1s 的行的索引。 此方法的时间复杂度为O(m * n)
,其中m
是矩阵中的行数,n
是矩阵中的列数。
我们可以做得更好。 由于每一行都已排序,因此我们可以使用二分搜索在每一行中计数 1。 我们在每一行中找到 1 的第一个实例的索引。 1 的计数等于列总数减去前 1 的索引。
请参见以下代码,以实现上述方法。
C++
// CPP program to find the row
// with maximum number of 1s
#include <bits/stdc++.h>
using namespace std;
#define R 4
#define C 4
// 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);
// If element is not first 1, recur for left side
else
return first(arr, low, (mid -1));
}
return -1;
}
// Function that returns index of row
// with maximum number of 1s.
int rowWithMax1s(bool mat[R][C])
{
// Initialize max values
int max_row_index = 0, max = -1;
// 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 Code
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;
}
// This is code is contributed by rathbhupendra
C
// C program to find the row
// with maximum number of 1s
#include <stdio.h>
#define R 4
#define C 4
// 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);
// If element is not first 1, recur for left side
else
return first(arr, low, (mid -1));
}
return -1;
}
// Function that returns index of row
// with maximum number of 1s.
int rowWithMax1s(bool mat[R][C])
{
// Initialize max values
int max_row_index = 0, max = -1;
// 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 Code
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;
}
Java
// Java program to find the row
// with maximum number of 1s
import java.io.*;
class GFG {
static int R = 4, C = 4;
// Function to find the index of first index
// of 1 in a boolean array arr[]
static int first(int 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);
// If element is not first 1, recur for left side
else
return first(arr, low, (mid - 1));
}
return -1;
}
// Function that returns index of row
// with maximum number of 1s.
static int rowWithMax1s(int mat[][])
{
// Initialize max values
int max_row_index = 0, max = -1;
// 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 Code
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));
}
}
// This code is contributed by 'Gitanjali'.
Python 3
# Python3 program to find the row
# with maximum number of 1s
# Function to find the index
# of first index of 1 in a
# boolean array arr[]
def first( arr, low, high):
if high >= low:
# Get the middle index
mid = low + (high - low)//2
# Check if the element at
# middle index is first 1
if (mid == 0 or arr[mid - 1] == 0) and arr[mid] == 1:
return mid
# If the element is 0,
# recur for right side
elif arr[mid] == 0:
return first(arr, (mid + 1), high)
# If element is not first 1,
# recur for left side
else:
return first(arr, low, (mid - 1))
return -1
# Function that returns
# index of row with maximum
# number of 1s.
def rowWithMax1s( mat):
# Initialize max values
R = len(mat)
C = len(mat[0])
max_row_index = 0
max = -1
# Traverse for each row and
# count number of 1s by finding
# the index of first 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
# Driver Code
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))
# This code is contributed
# by shreyanshi_arun
C
// C# program to find the row with maximum
// number of 1s
using System;
class GFG
{
public static int R = 4, C = 4;
// Function to find the index of first index
// of 1 in a boolean array arr[]
public static int first(int[] 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);
}
// If element is not first 1, recur
// for left side
else
{
return first(arr, low, (mid - 1));
}
}
return -1;
}
// Function that returns index of row
// with maximum number of 1s.
public static int rowWithMax1s(int[][] mat)
{
// Initialize max values
int max_row_index = 0, max = -1;
// 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 Code
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));
}
}
// This code is contributed by Shrikant13
PHP
<?php
// PHP program to find the row
// with maximum number of 1s
define("R", 4);
define("C", 4);
// Function to find the index of first
// index of 1 in a boolean array arr[]
function first($arr, $low, $high)
{
if($high >= $low)
{
// Get the middle index
$mid = $low + intval(($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);
// If element is not first 1, recur
// for left side
else
return first($arr, $low, ($mid - 1));
}
return -1;
}
// Function that returns index of row
// with maximum number of 1s.
function rowWithMax1s($mat)
{
// Initialize max values
$max_row_index = 0;
$max = -1;
// Traverse for each row and count number
// of 1s by finding the index of first 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;
}
// Driver Code
$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);
// This code is contributed by rathbhupendra
?>
输出:
Index of row with maximum 1s is 2
时间复杂度:O(mLogn)
其中m
是矩阵中的行数,n
是矩阵中的列数。
上述解决方案可以进一步优化。 我们首先检查该行是否比最大行数多1,而不是对每一行进行二进制搜索。 如果该行具有更多的 1,则仅在该行中计数 1。 另外,要连续计算 1s,我们不会在整行中进行二进制搜索,而是在最后一个最大值的索引之前进行搜索。
以下是上述解决方案的优化版本。
C++
#include <bits/stdc++.h>
using namespace std;
// The main function that returns index
// of row with maximum number of 1s.
int rowWithMax1s(bool mat[R][C])
{
int i, index;
// Initialize max using values from first row.
int max_row_index = 0;
int max = first(mat[0], 0, C - 1);
// Traverse for each row and count number of 1s
// by finding the index of first 1
for (i = 1; i < R; i++)
{
// Count 1s in this row only if this row
// has more 1s than max so far
// Count 1s in this row only if this row
// has more 1s than max so far
if (max != -1 && mat[i][C - max - 1] == 1)
{
// Note the optimization here also
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;
}
// This code is contributed by rathbhupendra
C
// The main function that returns index of row with maximum number of 1s.
int rowWithMax1s(bool mat[R][C])
{
int i, index;
// Initialize max using values from first row.
int max_row_index = 0;
int max = first(mat[0], 0, C-1);
// Traverse for each row and count number of 1s by finding the index
// of first 1
for (i = 1; i < R; i++)
{
// Count 1s in this row only if this row has more 1s than
// max so far
// Count 1s in this row only if this row has more 1s than
// max so far
if (max != -1 && mat[i][C-max-1] == 1)
{
// Note the optimization here also
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)
,意志解决方案的平均效果更好。 感谢 Naveen Kumar Singh 建议上述解决方案。
上述解决方案的最坏情况发生在如下矩阵中。
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++ 实现。
// The main function that returns index of row with maximum number of 1s.
int rowWithMax1s(bool mat[R][C])
{
// Initialize first row as row with max 1s
int max_row_index = 0;
// The function first() returns index of first 1 in row 0.
// Use this index to initialize the index of leftmost 1 seen so far
int j = first(mat[0], 0, C-1);
if (j == -1) // if 1 is not present in first row
j = C - 1;
for (int i = 1; i < R; i++)
{
// Move left until a 0 is found
while (j >= 0 && mat[i][j] == 1)
{
j = j-1; // Update the index of leftmost 1 seen so far
max_row_index = i; // Update max_row_index
}
}
return max_row_index;
感谢 Tylor,Ankan 和 Palash 的投入。
版权属于:月萌API www.moonapi.com,转载请注明出处