Given a matrix mat[][], where every row is sorted in increasing order, find any one element that is common to all rows. If no such element exists, return -1.
Examples:
Input: mat[][] = [[1, 2, 3, 4, 5],
[2, 4, 5, 8, 10],
[3, 5, 7, 9, 11],
[1, 3, 5, 7, 9]]
Output: 5
Explanation: The element 5 is present in every row, so it is returned.Input: mat[][] = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
Output: -1
Explanation: There is no element that appears in all rows, so the answer is -1.
Table of Content
[Naive Approach] Counting the Occurrences - O(m*n*m) Time and O(1) Space
We take each element from the first row and check whether this element appears in every other row. For every candidate element, we scan the entire row to see if it exists there or not. If an element from the first row is found in all rows, we return it as the common element. If none of the elements from the first row satisfy this condition, we return -1.
//Driver Code Starts
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//Driver Code Ends
int findCommon(vector<vector<int>> &arr){
int n = arr.size();
int m = arr[0].size();
int ans = -1;
for(int i = 0; i < m; i++){
// Traverse the first row
int check = arr[0][i];
int count = 1;
for(int j = 1; j < n; j++){
for(int k = 0; k < m; k++){
// break out of the loop
// if element is found
if(arr[j][k] == check){
count++;
break;
}
}
}
if(count == n){
ans = arr[0][i];
break;
}
}
return ans;
}
//Driver Code Starts
int main() {
vector<vector<int>> arr = {
{1, 2, 3, 4, 5},
{2, 4, 5, 8, 10},
{3, 5, 7, 9, 11},
{1, 3, 5, 7, 9}
};
int ans = findCommon(arr);
cout << ans << endl;
return 0;
}
//Driver Code Ends
//Driver Code Starts
class GfG {
//Driver Code Ends
static int findCommon(int[][] arr) {
int n = arr.length;
int m = arr[0].length;
int ans = -1;
for (int i = 0; i < m; i++) {
// Traverse the first row
int check = arr[0][i];
int count = 1;
for (int j = 1; j < n; j++) {
for (int k = 0; k < m; k++) {
// break out of the loop
// if element is found
if (arr[j][k] == check) {
count++;
break;
}
}
}
if (count == n) {
ans = arr[0][i];
break;
}
}
return ans;
}
//Driver Code Starts
public static void main(String[] args) {
int[][] arr = {
{1, 2, 3, 4, 5},
{2, 4, 5, 8, 10},
{3, 5, 7, 9, 11},
{1, 3, 5, 7, 9}
};
int ans = findCommon(arr);
System.out.println(ans);
}
}
//Driver Code Ends
def findCommon(arr):
n = len(arr)
m = len(arr[0])
ans = -1
for i in range(m):
# Traverse the first row
check = arr[0][i]
count = 1
for j in range(1, n):
for k in range(m):
# break out of the loop
# if element is found
if arr[j][k] == check:
count += 1
break
if count == n:
ans = arr[0][i]
break
return ans
#Driver Code Starts
if __name__ == "__main__":
arr = [
[1, 2, 3, 4, 5],
[2, 4, 5, 8, 10],
[3, 5, 7, 9, 11],
[1, 3, 5, 7, 9]
]
ans = findCommon(arr)
print(ans)
#Driver Code Ends
//Driver Code Starts
using System;
class GFG {
//Driver Code Ends
static int findCommon(int[,] arr) {
int n = arr.GetLength(0);
int m = arr.GetLength(1);
int ans = -1;
for (int i = 0; i < m; i++)
{
// Traverse the first row
int check = arr[0, i];
int count = 1;
for (int j = 1; j < n; j++)
{
for (int k = 0; k < m; k++)
{
// break out of the loop
// if element is found
if (arr[j, k] == check)
{
count++;
break;
}
}
}
if (count == n)
{
ans = arr[0, i];
break;
}
}
return ans;
}
//Driver Code Starts
public static void Main()
{
int[,] arr = {
{1, 2, 3, 4, 5},
{2, 4, 5, 8, 10},
{3, 5, 7, 9, 11},
{1, 3, 5, 7, 9}
};
int ans = findCommon(arr);
Console.WriteLine(ans);
}
}
//Driver Code Ends
function findCommon(arr) {
let n = arr.length;
let m = arr[0].length;
let ans = -1;
for (let i = 0; i < m; i++) {
// Traverse the first row
let check = arr[0][i];
let count = 1;
for (let j = 1; j < n; j++) {
for (let k = 0; k < m; k++) {
// break out of the loop
// if element is found
if (arr[j][k] === check) {
count++;
break;
}
}
}
if (count === n) {
ans = arr[0][i];
break;
}
}
return ans;
}
//Driver Code Starts
// Driver code
const arr = [
[1, 2, 3, 4, 5],
[2, 4, 5, 8, 10],
[3, 5, 7, 9, 11],
[1, 3, 5, 7, 9]
];
const ans = findCommon(arr);
console.log(ans);
//Driver Code Ends
Output
5
[Better Approach] Using Hash Table- O(n * m) Time and O(n * m) Space
Since every row in the matrix is sorted, all duplicates in a row appear together. We use this fact by scanning each row only once and counting each distinct element using a hash map.
For each row:
- We increment the frequency of the first element.
- For every next element, we only increase its frequency if it is different from the previous one, ensuring that duplicates are not counted multiple times within the same row.
After processing all rows, any element whose frequency becomes equal to the number of rows must have appeared in every row, and thus it is a common element.
If no such element exists, we return -1.
//Driver Code Starts
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
using namespace std;
//Driver Code Ends
int findCommon(vector<vector<int>> &arr) {
int n = arr.size();
int m = arr[0].size();
// A hash map to store count of elements
unordered_map<int, int> cnt;
int i, j;
for (i = 0; i < n; i++) {
// Increment the count of first
// element of the row
cnt[arr[i][0]]++;
// Starting from the second element
// of the current row
for (j = 1; j < m; j++) {
// count only distinct elements in the same row
if (arr[i][j] != arr[i][j - 1])
cnt[arr[i][j]]++;
}
}
// Find element having count equal to number of rows
for (auto ele : cnt) {
if (ele.second == n)
return ele.first;
}
// No such element found
return -1;
}
//Driver Code Starts
int main() {
vector<vector<int>>arr = {
{ 1, 2, 3, 4, 5 },
{ 2, 4, 5, 8, 10 },
{ 3, 5, 7, 9, 11 },
{ 1, 3, 5, 7, 9 },
};
int result = findCommon(arr);
cout << result << endl;
return 0;
}
//Driver Code Ends
//Driver Code Starts
import java.util.HashMap;
import java.util.Map;
class GFG {
//Driver Code Ends
static int findCommon(int[][] arr) {
int n = arr.length;
int m = arr[0].length;
// A hash map to store count of elements
Map<Integer, Integer> cnt = new HashMap<>();
int i, j;
for (i = 0; i < n; i++) {
// Increment the count of first
// element of the row
cnt.put(arr[i][0], cnt.getOrDefault(arr[i][0], 0) + 1);
// Starting from the second element
// of the current row
for (j = 1; j < m; j++) {
// count only distinct elements in the same row
if (arr[i][j] != arr[i][j - 1]) {
cnt.put(arr[i][j], cnt.getOrDefault(arr[i][j], 0) + 1);
}
}
}
// Find element having count equal to number of rows
for (Map.Entry<Integer, Integer> ele : cnt.entrySet()) {
if (ele.getValue() == n) {
return ele.getKey();
}
}
// No such element found
return -1;
}
//Driver Code Starts
public static void main(String[] args) {
int[][] arr = {
{ 1, 2, 3, 4, 5 },
{ 2, 4, 5, 8, 10 },
{ 3, 5, 7, 9, 11 },
{ 1, 3, 5, 7, 9 }
};
int result = findCommon(arr);
System.out.println(result);
}
}
//Driver Code Ends
def findCommon(arr):
n = len(arr)
m = len(arr[0])
# map to store frequency of elements across rows
cnt = {}
for i in range(n):
# count the first element of each row
cnt[arr[i][0]] = cnt.get(arr[i][0], 0) + 1
# count only distinct elements in the same row
for j in range(1, m):
if arr[i][j] != arr[i][j - 1]:
cnt[arr[i][j]] = cnt.get(arr[i][j], 0) + 1
# find element that appears in all rows
for ele, c in cnt.items():
if c == n:
return ele
return -1
#Driver Code Starts
if __name__ == '__main__':
arr = [
[1, 2, 3, 4, 5],
[2, 4, 5, 8, 10],
[3, 5, 7, 9, 11],
[1, 3, 5, 7, 9]
]
print(findCommon(arr))
#Driver Code Ends
//Driver Code Starts
using System;
using System.Collections.Generic;
class GFG
{
//Driver Code Ends
static int findCommon(int[,] arr)
{
int n = arr.GetLength(0);
int m = arr.GetLength(1);
// A hash map to store count of elements
Dictionary<int, int> cnt = new Dictionary<int, int>();
int i, j;
for (i = 0; i < n; i++)
{
// Increment the count of first
// element of the row
int first = arr[i, 0];
if (!cnt.ContainsKey(first))
cnt[first] = 0;
cnt[first]++;
// Starting from the second element
// of the current row
for (j = 1; j < m; j++)
{
// count only distinct elements in the same row
if (arr[i, j] != arr[i, j - 1])
{
int val = arr[i, j];
if (!cnt.ContainsKey(val))
cnt[val] = 0;
cnt[val]++;
}
}
}
// Find element having count equal to number of rows
foreach (var kvp in cnt)
{
if (kvp.Value == n)
return kvp.Key;
}
// No such element found
return -1;
}
//Driver Code Starts
static void Main()
{
int[,] arr = {
{ 1, 2, 3, 4, 5 },
{ 2, 4, 5, 8, 10 },
{ 3, 5, 7, 9, 11 },
{ 1, 3, 5, 7, 9 }
};
int result = findCommon(arr);
Console.WriteLine(result);
}
}
//Driver Code Ends
function findCommon(arr) {
const n = arr.length;
const m = arr[0].length;
// A hash map to store count of elements
const cnt = new Map();
for (let i = 0; i < n; i++) {
// Increment the count of first
// element of the row
cnt.set(arr[i][0], (cnt.get(arr[i][0]) || 0) + 1);
// Starting from the second element
// of the current row
for (let j = 1; j < m; j++) {
// count only distinct elements in the same row
if (arr[i][j] !== arr[i][j - 1]) {
cnt.set(arr[i][j], (cnt.get(arr[i][j]) || 0) + 1);
}
}
}
// Find element having count equal to number of rows
for (const [key, value] of cnt.entries()) {
if (value === n) {
return key;
}
}
// No such element found
return -1;
}
//Driver Code Starts
// Driver Code
const arr = [
[1, 2, 3, 4, 5],
[2, 4, 5, 8, 10],
[3, 5, 7, 9, 11],
[1, 3, 5, 7, 9]
];
const result = findCommon(arr);
console.log(result);
//Driver Code Ends
Output
5
[Expected Approach] Pointer Based Approach - O(n * m) Time and O(n) Space
Since every row is already sorted, we use a multi-pointer technique to find a common element.
We place one pointer at the first column of each row. At each step, we compare the values pointed to:
- If all pointers point to the same value, that value is the common element.
- Otherwise, we find the maximum among the pointed values.
- We move forward (right) the pointer of every row whose value is smaller than this maximum, because only the smaller values need to catch up to the largest one.
If any pointer moves beyond the last column, then no common element exists.
//Driver Code Starts
#include <iostream>
#include <vector>
using namespace std;
//Driver Code Ends
int findcommon(vector<vector<int>> &mat) {
int n = mat.size();
int m = mat[0].size();
// pointers for each row (start from first column)
vector<int> ptr(n, 0);
while (true) {
// get maximum among all current values
int mx = mat[0][ptr[0]];
for (int i = 1; i < n; i++) {
mx = max(mx, mat[i][ptr[i]]);
}
// check if all rows already have this maximum
bool allequal = true;
for (int i = 0; i < n; i++) {
if (mat[i][ptr[i]] != mx) {
allequal = false;
break;
}
}
if (allequal) return mx;
// move forward those rows which have smaller values
for (int i = 0; i < n; i++) {
if (mat[i][ptr[i]] < mx) {
ptr[i]++;
// pointer out of range
if (ptr[i] == m) return -1;
}
}
}
}
//Driver Code Starts
int main() {
vector<vector<int>> arr = {
{1, 2, 3, 4, 5},
{2, 4, 5, 8, 10},
{3, 5, 7, 9, 11},
{1, 3, 5, 7, 9}
};
cout << findcommon(arr);
return 0;
}
//Driver Code Ends
//Driver Code Starts
class GFG {
//Driver Code Ends
static int findcommon(int[][] mat) {
int n = mat.length;
int m = mat[0].length;
// pointers for each row (start from first column)
int[] ptr = new int[n];
while (true) {
// find maximum value among current pointers
int mx = mat[0][ptr[0]];
for (int i = 1; i < n; i++)
mx = Math.max(mx, mat[i][ptr[i]]);
// check if all rows point to same value
boolean allequal = true;
for (int i = 0; i < n; i++) {
if (mat[i][ptr[i]] != mx) {
allequal = false;
break;
}
}
if (allequal) return mx;
// move rows whose value is smaller than max
for (int i = 0; i < n; i++) {
if (mat[i][ptr[i]] < mx) {
ptr[i]++;
// out of range
if (ptr[i] == m) return -1;
}
}
}
}
//Driver Code Starts
public static void main(String[] args) {
int[][] arr = {
{1, 2, 3, 4, 5},
{2, 4, 5, 8, 10},
{3, 5, 7, 9, 11},
{1, 3, 5, 7, 9}
};
System.out.println(findcommon(arr));
}
}
//Driver Code Ends
def findcommon(mat):
n = len(mat)
m = len(mat[0])
# pointers for each row (start from first column)
ptr = [0] * n
while True:
# find maximum value among current pointers
mx = mat[0][ptr[0]]
for i in range(1, n):
mx = max(mx, mat[i][ptr[i]])
# check if all rows point to same value
allequal = True
for i in range(n):
if mat[i][ptr[i]] != mx:
allequal = False
break
if allequal:
return mx
# move rows whose value is smaller than max
for i in range(n):
if mat[i][ptr[i]] < mx:
ptr[i] += 1
# out of range
if ptr[i] == m:
return -1
#Driver Code Starts
if __name__ == '__main__':
arr = [
[1, 2, 3, 4, 5],
[2, 4, 5, 8, 10],
[3, 5, 7, 9, 11],
[1, 3, 5, 7, 9]
]
print(findcommon(arr))
#Driver Code Ends
//Driver Code Starts
using System;
class GFG {
//Driver Code Ends
static int findcommon(int[,] mat) {
int n = mat.GetLength(0);
int m = mat.GetLength(1);
// pointers for each row (start from first column)
int[] ptr = new int[n];
while (true)
{
// find maximum value among current pointers
int mx = mat[0, ptr[0]];
for (int i = 1; i < n; i++)
mx = Math.Max(mx, mat[i, ptr[i]]);
// check if all rows point to same value
bool allequal = true;
for (int i = 0; i < n; i++)
{
if (mat[i, ptr[i]] != mx)
{
allequal = false;
break;
}
}
if (allequal) return mx;
// move rows whose value is smaller than max
for (int i = 0; i < n; i++)
{
if (mat[i, ptr[i]] < mx)
{
ptr[i]++;
// out of range
if (ptr[i] == m) return -1;
}
}
}
}
//Driver Code Starts
static void Main()
{
int[,] arr = {
{1, 2, 3, 4, 5},
{2, 4, 5, 8, 10},
{3, 5, 7, 9, 11},
{1, 3, 5, 7, 9}
};
Console.WriteLine(findcommon(arr));
}
}
//Driver Code Ends
function findcommon(mat) {
let n = mat.length;
let m = mat[0].length;
// pointers for each row (start from first column)
let ptr = Array(n).fill(0);
while (true) {
// find maximum value among current pointers
let mx = mat[0][ptr[0]];
for (let i = 1; i < n; i++)
mx = Math.max(mx, mat[i][ptr[i]]);
// check if all rows point to same value
let allequal = true;
for (let i = 0; i < n; i++) {
if (mat[i][ptr[i]] !== mx) {
allequal = false;
break;
}
}
if (allequal) return mx;
// move rows whose value is smaller than max
for (let i = 0; i < n; i++) {
if (mat[i][ptr[i]] < mx) {
ptr[i]++;
// out of range
if (ptr[i] === m) return -1;
}
}
}
}
//Driver Code Starts
// Driver Code
let arr = [
[1, 2, 3, 4, 5],
[2, 4, 5, 8, 10],
[3, 5, 7, 9, 11],
[1, 3, 5, 7, 9]
];
console.log(findcommon(arr));
//Driver Code Ends
Output
5