在给定的逐行排序矩阵的所有行中找到一个公共元素
给定一个矩阵,其中每一行都按升序排序。编写一个函数,在所有行中查找并返回一个公共元素。如果没有公共元素,则返回 -1。
例子:
Input: mat[4][5] = { {1, 2, 3, 4, 5},
{2, 4, 5, 8, 10},
{3, 5, 7, 9, 11},
{1, 3, 5, 7, 9},
};
Output: 5
一个O(m*n*n) 的简单解决方案是获取第一行的每个元素并在所有其他行中搜索它,直到找到一个公共元素。该解决方案的时间复杂度为 O(m*n*n),其中 m 是行数,n 是给定矩阵中的列数。如果我们使用二分搜索而不是线性搜索,这可以改进为 O(m*n*Logn)。
我们可以使用类似于 Merge Sort 的方法在 O(mn) 时间内解决这个问题。这个想法是从每一行的最后一列开始。如果最后一列的元素都相同,那么我们找到了共同的元素。否则,我们会找到所有最后一列的最小值。一旦找到最小元素,我们就知道最后一列中的所有其他元素不可能是公共元素,因此我们减少所有行的最后一列索引,除了具有最小值的行。我们不断重复这些步骤,直到当前最后一列的所有元素都不相同,或者最后一列索引达到 0。
下面是上述想法的实现。
C++
// A C++ program to find a common element in all rows of a
// row wise sorted array
#include
using namespace std;
// Specify number of rows and columns
#define M 4
#define N 5
// Returns common element in all rows of mat[M][N]. If there is no
// common element, then -1 is returned
int findCommon(int mat[M][N])
{
// An array to store indexes of current last column
int column[M];
int min_row; // To store index of row whose current
// last element is minimum
// Initialize current last element of all rows
int i;
for (i = 0; i < M; i++)
column[i] = N - 1;
min_row = 0; // Initialize min_row as first row
// Keep finding min_row in current last column, till either
// all elements of last column become same or we hit first column.
while (column[min_row] >= 0) {
// Find minimum in current last column
for (i = 0; i < M; i++) {
if (mat[i][column[i]] < mat[min_row][column[min_row]])
min_row = i;
}
// eq_count is count of elements equal to minimum in current last
// column.
int eq_count = 0;
// Traverse current last column elements again to update it
for (i = 0; i < M; i++) {
// Decrease last column index of a row whose value is more
// than minimum.
if (mat[i][column[i]] > mat[min_row][column[min_row]]) {
if (column[i] == 0)
return -1;
column[i] -= 1; // Reduce last column index by 1
}
else
eq_count++;
}
// If equal count becomes M, return the value
if (eq_count == M)
return mat[min_row][column[min_row]];
}
return -1;
}
// Driver Code
int main()
{
int mat[M][N] = {
{ 1, 2, 3, 4, 5 },
{ 2, 4, 5, 8, 10 },
{ 3, 5, 7, 9, 11 },
{ 1, 3, 5, 7, 9 },
};
int result = findCommon(mat);
if (result == -1)
cout << "No common element";
else
cout << "Common element is " << result;
return 0;
}
// This code is contributed
// by Akanksha Rai
C
// A C program to find a common element in all rows of a
// row wise sorted array
#include
// Specify number of rows and columns
#define M 4
#define N 5
// Returns common element in all rows of mat[M][N]. If there is no
// common element, then -1 is returned
int findCommon(int mat[M][N])
{
// An array to store indexes of current last column
int column[M];
int min_row; // To store index of row whose current
// last element is minimum
// Initialize current last element of all rows
int i;
for (i = 0; i < M; i++)
column[i] = N - 1;
min_row = 0; // Initialize min_row as first row
// Keep finding min_row in current last column, till either
// all elements of last column become same or we hit first column.
while (column[min_row] >= 0) {
// Find minimum in current last column
for (i = 0; i < M; i++) {
if (mat[i][column[i]] < mat[min_row][column[min_row]])
min_row = i;
}
// eq_count is count of elements equal to minimum in current last
// column.
int eq_count = 0;
// Traverse current last column elements again to update it
for (i = 0; i < M; i++) {
// Decrease last column index of a row whose value is more
// than minimum.
if (mat[i][column[i]] > mat[min_row][column[min_row]]) {
if (column[i] == 0)
return -1;
column[i] -= 1; // Reduce last column index by 1
}
else
eq_count++;
}
// If equal count becomes M, return the value
if (eq_count == M)
return mat[min_row][column[min_row]];
}
return -1;
}
// driver program to test above function
int main()
{
int mat[M][N] = {
{ 1, 2, 3, 4, 5 },
{ 2, 4, 5, 8, 10 },
{ 3, 5, 7, 9, 11 },
{ 1, 3, 5, 7, 9 },
};
int result = findCommon(mat);
if (result == -1)
printf("No common element");
else
printf("Common element is %d", result);
return 0;
}
Java
// A Java program to find a common
// element in all rows of a
// row wise sorted array
class GFG {
// Specify number of rows and columns
static final int M = 4;
static final int N = 5;
// Returns common element in all rows
// of mat[M][N]. If there is no
// common element, then -1 is
// returned
static int findCommon(int mat[][])
{
// An array to store indexes
// of current last column
int column[] = new int[M];
// To store index of row whose current
// last element is minimum
int min_row;
// Initialize current last element of all rows
int i;
for (i = 0; i < M; i++)
column[i] = N - 1;
// Initialize min_row as first row
min_row = 0;
// Keep finding min_row in current last column, till either
// all elements of last column become same or we hit first column.
while (column[min_row] >= 0) {
// Find minimum in current last column
for (i = 0; i < M; i++) {
if (mat[i][column[i]] < mat[min_row][column[min_row]])
min_row = i;
}
// eq_count is count of elements equal to minimum in current last
// column.
int eq_count = 0;
// Traverse current last column elements again to update it
for (i = 0; i < M; i++) {
// Decrease last column index of a row whose value is more
// than minimum.
if (mat[i][column[i]] > mat[min_row][column[min_row]]) {
if (column[i] == 0)
return -1;
// Reduce last column index by 1
column[i] -= 1;
}
else
eq_count++;
}
// If equal count becomes M,
// return the value
if (eq_count == M)
return mat[min_row][column[min_row]];
}
return -1;
}
// Driver code
public static void main(String[] args)
{
int mat[][] = { { 1, 2, 3, 4, 5 },
{ 2, 4, 5, 8, 10 },
{ 3, 5, 7, 9, 11 },
{ 1, 3, 5, 7, 9 } };
int result = findCommon(mat);
if (result == -1)
System.out.print("No common element");
else
System.out.print("Common element is " + result);
}
}
// This code is contributed by Anant Agarwal.
Python 3
# Python 3 program to find a common element
# in all rows of a row wise sorted array
# Specify number of rows
# and columns
M = 4
N = 5
# Returns common element in all rows
# of mat[M][N]. If there is no common
# element, then -1 is returned
def findCommon(mat):
# An array to store indexes of
# current last column
column = [N - 1] * M
min_row = 0 # Initialize min_row as first row
# Keep finding min_row in current last
# column, till either all elements of
# last column become same or we hit first column.
while (column[min_row] >= 0):
# Find minimum in current last column
for i in range(M):
if (mat[i][column[i]] <
mat[min_row][column[min_row]]):
min_row = i
# eq_count is count of elements equal
# to minimum in current last column.
eq_count = 0
# Traverse current last column elements
# again to update it
for i in range(M):
# Decrease last column index of a row
# whose value is more than minimum.
if (mat[i][column[i]] >
mat[min_row][column[min_row]]):
if (column[i] == 0):
return -1
column[i] -= 1 # Reduce last column
# index by 1
else:
eq_count += 1
# If equal count becomes M, return the value
if (eq_count == M):
return mat[min_row][column[min_row]]
return -1
# Driver Code
if __name__ == "__main__":
mat = [[1, 2, 3, 4, 5],
[2, 4, 5, 8, 10],
[3, 5, 7, 9, 11],
[1, 3, 5, 7, 9]]
result = findCommon(mat)
if (result == -1):
print("No common element")
else:
print("Common element is", result)
# This code is contributed by ita_c
C#
// A C# program to find a common
// element in all rows of a
// row wise sorted array
using System;
class GFG {
// Specify number of rows and columns
static int M = 4;
static int N = 5;
// Returns common element in all rows
// of mat[M][N]. If there is no
// common element, then -1 is
// returned
static int findCommon(int[, ] mat)
{
// An array to store indexes
// of current last column
int[] column = new int[M];
// To store index of row whose
// current last element is minimum
int min_row;
// Initialize current last element
// of all rows
int i;
for (i = 0; i < M; i++)
column[i] = N - 1;
// Initialize min_row as first row
min_row = 0;
// Keep finding min_row in current
// last column, till either all
// elements of last column become
// same or we hit first column.
while (column[min_row] >= 0) {
// Find minimum in current
// last column
for (i = 0; i < M; i++) {
if (mat[i, column[i]] < mat[min_row, column[min_row]])
min_row = i;
}
// eq_count is count of elements
// equal to minimum in current
// last column.
int eq_count = 0;
// Traverse current last column
// elements again to update it
for (i = 0; i < M; i++) {
// Decrease last column index
// of a row whose value is more
// than minimum.
if (mat[i, column[i]] > mat[min_row, column[min_row]]) {
if (column[i] == 0)
return -1;
// Reduce last column index
// by 1
column[i] -= 1;
}
else
eq_count++;
}
// If equal count becomes M,
// return the value
if (eq_count == M)
return mat[min_row,
column[min_row]];
}
return -1;
}
// Driver code
public static void Main()
{
int[, ] mat = { { 1, 2, 3, 4, 5 },
{ 2, 4, 5, 8, 10 },
{ 3, 5, 7, 9, 11 },
{ 1, 3, 5, 7, 9 } };
int result = findCommon(mat);
if (result == -1)
Console.Write("No common element");
else
Console.Write("Common element is "
+ result);
}
}
// This code is contributed by Sam007.
Javascript
C++
// C++ implementation of the approach
#include
using namespace std;
// Specify number of rows and columns
#define M 4
#define N 5
// Returns common element in all rows of mat[M][N]. If there is no
// common element, then -1 is returned
int findCommon(int mat[M][N])
{
// A hash map to store count of elements
unordered_map cnt;
int i, j;
for (i = 0; i < M; i++) {
// Increment the count of first
// element of the row
cnt[mat[i][0]]++;
// Starting from the second element
// of the current row
for (j = 1; j < N; j++) {
// If current element is different from
// the previous element i.e. it is appearing
// for the first time in the current row
if (mat[i][j] != mat[i][j - 1])
cnt[mat[i][j]]++;
}
}
// Find element having count equal to number of rows
for (auto ele : cnt) {
if (ele.second == M)
return ele.first;
}
// No such element found
return -1;
}
// Driver Code
int main()
{
int mat[M][N] = {
{ 1, 2, 3, 4, 5 },
{ 2, 4, 5, 8, 10 },
{ 3, 5, 7, 9, 11 },
{ 1, 3, 5, 7, 9 },
};
int result = findCommon(mat);
if (result == -1)
cout << "No common element";
else
cout << "Common element is " << result;
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
// Specify number of rows and columns
static int M = 4;
static int N = 5;
// Returns common element in all rows of mat[M][N].
// If there is no common element, then -1 is returned
static int findCommon(int mat[][])
{
// A hash map to store count of elements
HashMap cnt = new HashMap();
int i, j;
for (i = 0; i < M; i++)
{
// Increment the count of first
// element of the row
if(cnt.containsKey(mat[i][0]))
{
cnt.put(mat[i][0],
cnt.get(mat[i][0]) + 1);
}
else
{
cnt.put(mat[i][0], 1);
}
// Starting from the second element
// of the current row
for (j = 1; j < N; j++)
{
// If current element is different from
// the previous element i.e. it is appearing
// for the first time in the current row
if (mat[i][j] != mat[i][j - 1])
if(cnt.containsKey(mat[i][j]))
{
cnt.put(mat[i][j],
cnt.get(mat[i][j]) + 1);
}
else
{
cnt.put(mat[i][j], 1);
}
}
}
// Find element having count
// equal to number of rows
for (Map.Entry ele : cnt.entrySet())
{
if (ele.getValue() == M)
return ele.getKey();
}
// No such element found
return -1;
}
// Driver Code
public static void main(String[] args)
{
int mat[][] = {{ 1, 2, 3, 4, 5 },
{ 2, 4, 5, 8, 10 },
{ 3, 5, 7, 9, 11 },
{ 1, 3, 5, 7, 9 }};
int result = findCommon(mat);
if (result == -1)
System.out.println("No common element");
else
System.out.println("Common element is " + result);
}
}
// This code is contributed by Rajput-Ji
Python
# Python3 implementation of the approach
from collections import defaultdict
# Specify number of rows and columns
M = 4
N = 5
# Returns common element in all rows of
# mat[M][N]. If there is no
# common element, then -1 is returned
def findCommon(mat):
global M
global N
# A hash map to store count of elements
cnt = dict()
cnt = defaultdict(lambda: 0, cnt)
i = 0
j = 0
while (i < M ):
# Increment the count of first
# element of the row
cnt[mat[i][0]] = cnt[mat[i][0]] + 1
j = 1
# Starting from the second element
# of the current row
while (j < N ) :
# If current element is different from
# the previous element i.e. it is appearing
# for the first time in the current row
if (mat[i][j] != mat[i][j - 1]):
cnt[mat[i][j]] = cnt[mat[i][j]] + 1
j = j + 1
i = i + 1
# Find element having count equal to number of rows
for ele in cnt:
if (cnt[ele] == M):
return ele
# No such element found
return -1
# Driver Code
mat = [[1, 2, 3, 4, 5 ],
[2, 4, 5, 8, 10],
[3, 5, 7, 9, 11],
[1, 3, 5, 7, 9 ],]
result = findCommon(mat)
if (result == -1):
print("No common element")
else:
print("Common element is ", result)
# This code is contributed by Arnab Kundu
C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
class GFG
{
// Specify number of rows and columns
static int M = 4;
static int N = 5;
// Returns common element in all rows of mat[M,N].
// If there is no common element, then -1 is returned
static int findCommon(int [,]mat)
{
// A hash map to store count of elements
Dictionary cnt = new Dictionary();
int i, j;
for (i = 0; i < M; i++)
{
// Increment the count of first
// element of the row
if(cnt.ContainsKey(mat[i, 0]))
{
cnt[mat[i, 0]]= cnt[mat[i, 0]] + 1;
}
else
{
cnt.Add(mat[i, 0], 1);
}
// Starting from the second element
// of the current row
for (j = 1; j < N; j++)
{
// If current element is different from
// the previous element i.e. it is appearing
// for the first time in the current row
if (mat[i, j] != mat[i, j - 1])
if(cnt.ContainsKey(mat[i, j]))
{
cnt[mat[i, j]]= cnt[mat[i, j]] + 1;
}
else
{
cnt.Add(mat[i, j], 1);
}
}
}
// Find element having count
// equal to number of rows
foreach(KeyValuePair ele in cnt)
{
if (ele.Value == M)
return ele.Key;
}
// No such element found
return -1;
}
// Driver Code
public static void Main(String[] args)
{
int [,]mat = {{ 1, 2, 3, 4, 5 },
{ 2, 4, 5, 8, 10 },
{ 3, 5, 7, 9, 11 },
{ 1, 3, 5, 7, 9 }};
int result = findCommon(mat);
if (result == -1)
Console.WriteLine("No common element");
else
Console.WriteLine("Common element is " + result);
}
}
// This code is contributed by 29AjayKumar
Javascript
Common element is 5
上述代码的工作说明
让我们了解以下示例的上述代码的工作原理。
最初,最后一列数组中的条目是 N-1,即 {4, 4, 4, 4}
{1, 2, 3, 4, 5 },
{2, 4, 5, 8, 10 },
{3, 5, 7, 9, 11 },
{1, 3, 5, 7, 9 },
min_row 的值为 0,因此值大于 5 的行的最后一列索引值减 1。所以 column[] 变成 {4, 3, 3, 3}。
{1, 2, 3, 4, 5 },
{2, 4, 5, 8 , 10},
{3, 5, 7, 9 , 11},
{1, 3, 5, 7 , 9},
min_row 的值保持为 0,并且值大于 5 的行的最后一列索引的值减 1。所以 column[] 变为 {4, 2, 2, 2}。
{1, 2, 3, 4, 5 },
{2, 4, 5 , 8, 10},
{3, 5, 7 , 9, 11},
{1, 3, 5 , 7, 9},
min_row 的值保持为 0,值大于 5 的行的最后一列索引值减一。所以 column[] 变为 {4, 2, 1, 2}。
{1, 2, 3, 4, 5 },
{2, 4, 5 , 8, 10},
{3, 5 , 7, 9, 11},
{1, 3, 5 , 7, 9},
现在所有行的当前最后一列中的所有值都相同,因此返回 5。
基于散列的解决方案
我们也可以使用散列。即使行未排序,此解决方案也有效。它可用于打印所有常见元素。
Step1: Create a Hash Table with all key as distinct elements
of row1. Value for all these will be 0.
Step2:
For i = 1 to M-1
For j = 0 to N-1
If (mat[i][j] is already present in Hash Table)
If (And this is not a repetition in current row.
This can be checked by comparing HashTable value with
row number)
Update the value of this key in HashTable with current
row number
Step3: Iterate over HashTable and print all those keys for
which value = M
C++
// C++ implementation of the approach
#include
using namespace std;
// Specify number of rows and columns
#define M 4
#define N 5
// Returns common element in all rows of mat[M][N]. If there is no
// common element, then -1 is returned
int findCommon(int mat[M][N])
{
// A hash map to store count of elements
unordered_map cnt;
int i, j;
for (i = 0; i < M; i++) {
// Increment the count of first
// element of the row
cnt[mat[i][0]]++;
// Starting from the second element
// of the current row
for (j = 1; j < N; j++) {
// If current element is different from
// the previous element i.e. it is appearing
// for the first time in the current row
if (mat[i][j] != mat[i][j - 1])
cnt[mat[i][j]]++;
}
}
// Find element having count equal to number of rows
for (auto ele : cnt) {
if (ele.second == M)
return ele.first;
}
// No such element found
return -1;
}
// Driver Code
int main()
{
int mat[M][N] = {
{ 1, 2, 3, 4, 5 },
{ 2, 4, 5, 8, 10 },
{ 3, 5, 7, 9, 11 },
{ 1, 3, 5, 7, 9 },
};
int result = findCommon(mat);
if (result == -1)
cout << "No common element";
else
cout << "Common element is " << result;
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
// Specify number of rows and columns
static int M = 4;
static int N = 5;
// Returns common element in all rows of mat[M][N].
// If there is no common element, then -1 is returned
static int findCommon(int mat[][])
{
// A hash map to store count of elements
HashMap cnt = new HashMap();
int i, j;
for (i = 0; i < M; i++)
{
// Increment the count of first
// element of the row
if(cnt.containsKey(mat[i][0]))
{
cnt.put(mat[i][0],
cnt.get(mat[i][0]) + 1);
}
else
{
cnt.put(mat[i][0], 1);
}
// Starting from the second element
// of the current row
for (j = 1; j < N; j++)
{
// If current element is different from
// the previous element i.e. it is appearing
// for the first time in the current row
if (mat[i][j] != mat[i][j - 1])
if(cnt.containsKey(mat[i][j]))
{
cnt.put(mat[i][j],
cnt.get(mat[i][j]) + 1);
}
else
{
cnt.put(mat[i][j], 1);
}
}
}
// Find element having count
// equal to number of rows
for (Map.Entry ele : cnt.entrySet())
{
if (ele.getValue() == M)
return ele.getKey();
}
// No such element found
return -1;
}
// Driver Code
public static void main(String[] args)
{
int mat[][] = {{ 1, 2, 3, 4, 5 },
{ 2, 4, 5, 8, 10 },
{ 3, 5, 7, 9, 11 },
{ 1, 3, 5, 7, 9 }};
int result = findCommon(mat);
if (result == -1)
System.out.println("No common element");
else
System.out.println("Common element is " + result);
}
}
// This code is contributed by Rajput-Ji
Python
# Python3 implementation of the approach
from collections import defaultdict
# Specify number of rows and columns
M = 4
N = 5
# Returns common element in all rows of
# mat[M][N]. If there is no
# common element, then -1 is returned
def findCommon(mat):
global M
global N
# A hash map to store count of elements
cnt = dict()
cnt = defaultdict(lambda: 0, cnt)
i = 0
j = 0
while (i < M ):
# Increment the count of first
# element of the row
cnt[mat[i][0]] = cnt[mat[i][0]] + 1
j = 1
# Starting from the second element
# of the current row
while (j < N ) :
# If current element is different from
# the previous element i.e. it is appearing
# for the first time in the current row
if (mat[i][j] != mat[i][j - 1]):
cnt[mat[i][j]] = cnt[mat[i][j]] + 1
j = j + 1
i = i + 1
# Find element having count equal to number of rows
for ele in cnt:
if (cnt[ele] == M):
return ele
# No such element found
return -1
# Driver Code
mat = [[1, 2, 3, 4, 5 ],
[2, 4, 5, 8, 10],
[3, 5, 7, 9, 11],
[1, 3, 5, 7, 9 ],]
result = findCommon(mat)
if (result == -1):
print("No common element")
else:
print("Common element is ", result)
# This code is contributed by Arnab Kundu
C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
class GFG
{
// Specify number of rows and columns
static int M = 4;
static int N = 5;
// Returns common element in all rows of mat[M,N].
// If there is no common element, then -1 is returned
static int findCommon(int [,]mat)
{
// A hash map to store count of elements
Dictionary cnt = new Dictionary();
int i, j;
for (i = 0; i < M; i++)
{
// Increment the count of first
// element of the row
if(cnt.ContainsKey(mat[i, 0]))
{
cnt[mat[i, 0]]= cnt[mat[i, 0]] + 1;
}
else
{
cnt.Add(mat[i, 0], 1);
}
// Starting from the second element
// of the current row
for (j = 1; j < N; j++)
{
// If current element is different from
// the previous element i.e. it is appearing
// for the first time in the current row
if (mat[i, j] != mat[i, j - 1])
if(cnt.ContainsKey(mat[i, j]))
{
cnt[mat[i, j]]= cnt[mat[i, j]] + 1;
}
else
{
cnt.Add(mat[i, j], 1);
}
}
}
// Find element having count
// equal to number of rows
foreach(KeyValuePair ele in cnt)
{
if (ele.Value == M)
return ele.Key;
}
// No such element found
return -1;
}
// Driver Code
public static void Main(String[] args)
{
int [,]mat = {{ 1, 2, 3, 4, 5 },
{ 2, 4, 5, 8, 10 },
{ 3, 5, 7, 9, 11 },
{ 1, 3, 5, 7, 9 }};
int result = findCommon(mat);
if (result == -1)
Console.WriteLine("No common element");
else
Console.WriteLine("Common element is " + result);
}
}
// This code is contributed by 29AjayKumar
Javascript
Common element is 5