Given a matrix mat[][] of distinct values and an integer sum, find all the pairs in a given matrix whose summation is equal to the given sum.
Note: Each element of a pair must be from different rows i.e; the pair must not lie in the same row.
Examples:
Input : mat[][] = [[1, 3, 2, 4],
[5, 8, 7, 6],
[9, 10, 13, 11],
[12, 0, 14, 15]],
sum = 11
Output: [[1, 10], [3, 8], [2, 9], [4, 7], [11, 0]]Input : mat[][] = [[1, 5, 7],
[2, 6, 8],
[3, 4, 9]] ,
sum = 11
Output : [[2, 9], [3, 8], [5, 6]]
[Naive Approach] - Consider Every Element One by One - O(m2 x n2) Time and O(1) Space
A simple solution for this problem is to, one by one, take each element of all rows and find pairs starting from the next immediate row in the matrix.
//Driver Code Starts
#include <iostream>
#include<vector>
using namespace std;
//Driver Code Ends
vector<vector<int>> pairSum(vector<vector<int> >& mat, int sum)
{
int m = mat.size();
int n = mat[0].size();
int count = 0;
// for storing the result
vector<vector<int>>result;
// check every posible values
for (int i = 0; i < m; i++) {
for (int j = i + 1; j < m; j++) {
for (int k = 0; k < n; k++) {
for (int l = 0; l < n; l++) {
if (mat[i][k] + mat[j][l] == sum) {
result.push_back({mat[i][k],mat[j][l]});
}
}
}
}
}
return result;
}
//Driver Code Starts
int main()
{
int sum = 11;
vector<vector<int> > mat = { { 1, 3, 2, 4 },
{ 5, 8, 7, 6 },
{ 9, 10, 13, 11 },
{ 12, 0, 14, 15 } };
vector<vector<int>>result=pairSum(mat, sum);
// print the result
for(int i=0;i<result.size();i++){
cout<<"(" << result[i][0]<<", "<<result[i][1] <<")";
if(i!=result.size()-1){
cout<< ", ";
}
}
return 0;
}
//Driver Code Ends
//Driver Code Starts
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
//Driver Code Ends
public class GfG {
static List<List<Integer>> pairSum(int[][] mat, int sum) {
int m = mat.length;
int n = mat[0].length;
// for storing the result
List<List<Integer>> result = new ArrayList<>();
// check every possible values
for (int i = 0; i < m; i++) {
for (int j = i + 1; j < m; j++) {
for (int k = 0; k < n; k++) {
for (int l = 0; l < n; l++) {
if (mat[i][k] + mat[j][l] == sum) {
result.add(Arrays.asList(mat[i][k], mat[j][l]));
}
}
}
}
}
return result;
}
//Driver Code Starts
public static void main(String[] args) {
int sum = 11;
int[][] mat = {
{1, 3, 2, 4},
{5, 8, 7, 6},
{9, 10, 13, 11},
{12, 0, 14, 15}
};
List<List<Integer>> result = pairSum(mat, sum);
// print the result
for (int i = 0; i < result.size(); i++) {
System.out.print("(" + result.get(i).get(0) + ", " + result.get(i).get(1) + ")");
if (i != result.size() - 1) {
System.out.print(", ");
}
}
}
}
//Driver Code Ends
def pairSum(mat, total_sum):
m = len(mat)
n = len(mat[0])
# for storing the result
result = []
# check every possible values
for i in range(m):
for j in range(i + 1, m):
for k in range(n):
for l in range(n):
if mat[i][k] + mat[j][l] == total_sum:
result.append([mat[i][k], mat[j][l]])
return result
if __name__ == "__main__":
sum_val = 11
mat = [
[1, 3, 2, 4],
[5, 8, 7, 6],
[9, 10, 13, 11],
[12, 0, 14, 15]
]
result = pairSum(mat, sum_val)
# print the result
for i in range(len(result)):
print(f"({result[i][0]}, {result[i][1]})", end="")
if i != len(result) - 1:
print(", ", end="")
//Driver Code Starts
using System;
using System.Collections.Generic;
//Driver Code Ends
class GfG
{
static List<List<int>> PairSum(int[,] mat, int sum)
{
int m = mat.GetLength(0);
int n = mat.GetLength(1);
// for storing the result
List<List<int>> result = new List<List<int>>();
// check every possible values
for (int i = 0; i < m; i++)
{
for (int j = i + 1; j < m; j++)
{
for (int k = 0; k < n; k++)
{
for (int l = 0; l < n; l++)
{
if (mat[i, k] + mat[j, l] == sum)
{
result.Add(new List<int> { mat[i, k], mat[j, l] });
}
}
}
}
}
return result;
}
//Driver Code Starts
static void Main()
{
int sum = 11;
int[,] mat = {
{1, 3, 2, 4},
{5, 8, 7, 6},
{9, 10, 13, 11},
{12, 0, 14, 15}
};
var result = PairSum(mat, sum);
// print the result
for (int i = 0; i < result.Count; i++)
{
Console.Write("(" + result[i][0] + ", " + result[i][1] + ")");
if (i != result.Count - 1)
{
Console.Write(", ");
}
}
}
}
//Driver Code Ends
function pairSum(mat, sum) {
let m = mat.length;
let n = mat[0].length;
// for storing the result
let result = [];
// check every possible values
for (let i = 0; i < m; i++) {
for (let j = i + 1; j < m; j++) {
for (let k = 0; k < n; k++) {
for (let l = 0; l < n; l++) {
if (mat[i][k] + mat[j][l] === sum) {
result.push([mat[i][k], mat[j][l]]);
}
}
}
}
}
return result;
}
//Driver Code Starts
// driver code
let sum = 11;
let mat = [
[1, 3, 2, 4],
[5, 8, 7, 6],
[9, 10, 13, 11],
[12, 0, 14, 15]
];
let result = pairSum(mat, sum);
// print the result
for (let i = 0; i < result.length; i++) {
process.stdout.write(`(${result[i][0]}, ${result[i][1]})`);
if (i !== result.length - 1) {
process.stdout.write(", ");
}
}
//Driver Code Ends
[Better Approach] - Sorting and Two Pointer - O(mn Log n + mn2) Time and O(1) Space
The idea is to sort each row, then for each row select an element, and use two pointers to find the required pair in the other rows.
Steps:
- Sort all the rows in ascending order. The time complexity for this preprocessing will be O(m x n log n).
- Now we select each row one by one and find pair elements in the remaining rows after the current row.
- Take two iterators, left and right. left iterator points left corner of the current i'th row and right iterator points right corner of the next j'th row in which we are going to find a pair of elements.
- If mat[i][left] + mat[j][right] < sum then left++ i.e; move in i'th row towards the right corner, otherwise right++ i.e; move in j'th row towards the left corner
//Driver Code Starts
#include <iostream>
#include<vector>
using namespace std;
//Driver Code Ends
vector<vector<int>> pairSum(vector<vector<int>>& mat, int sum)
{
int n = mat.size();
vector<vector<int>>result;
// Sort all rows
for (int i=0; i<n; i++)
sort(mat[i].begin(), mat[i].end());
// select an element
for (int i=0; i<n-1; i++)
{
for (int j=i+1; j<n; j++)
{
// use two pointers for other rows
int left = 0, right = mat[j].size()-1;
while (left < mat[i].size() && right >= 0)
{
if ((mat[i][left] + mat[j][right]) == sum)
{
result.push_back({mat[i][left],mat[j][right]});
left++;
right--;
}
else
{
// two pointers moves
if ((mat[i][left] + mat[j][right]) < sum)
left++;
else
right--;
}
}
}
}
return result;
}
//Driver Code Starts
int main()
{
int sum = 11;
vector<vector<int>> mat = {{1, 3, 2, 4},
{5, 8, 7, 6},
{9, 10, 13, 11},
{12, 0, 14, 15}};
vector<vector<int>>result=pairSum(mat, sum);
for(auto&i:result){
cout<<"("<<i[0] <<", "<< i[1] <<"), ";
}
return 0;
}
//Driver Code Ends
//Driver Code Starts
import java.util.ArrayList;
import java.util.Arrays;
//Driver Code Ends
public class GfG {
static ArrayList<ArrayList<Integer>> pairSum(int[][] mat, int sum) {
int n = mat.length;
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
//sort all rows
for (int i = 0; i < n; i++)
Arrays.sort(mat[i]);
// select an element
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
// use two pointers for other rows
int left = 0, right = mat[j].length - 1;
while (left < mat[i].length && right >= 0) {
int s = mat[i][left] + mat[j][right];
if (s == sum) {
result.add(new ArrayList<>(Arrays.asList(mat[i][left], mat[j][right])));
left++;
right--;
}
else if (s < sum)
left++;
else
right--;
}
}
}
return result;
}
//Driver Code Starts
public static void main(String[] args) {
int sum = 11;
int[][] mat = {
{1, 3, 2, 4},
{5, 8, 7, 6},
{9, 10, 13, 11},
{12, 0, 14, 15}
};
ArrayList<ArrayList<Integer>> result = pairSum(mat, sum);
for (ArrayList<Integer> p : result)
System.out.print("(" + p.get(0) + ", " + p.get(1) + "), ");
}
}
//Driver Code Ends
def pairSum(mat, sum_val):
n = len(mat)
result = []
#sort all the rows
for i in range(n):
mat[i].sort()
# select an element
for i in range(n - 1):
for j in range(i + 1, n):
# use two pointers for other rows
left, right = 0, len(mat[j]) - 1
while left < len(mat[i]) and right >= 0:
if (mat[i][left] + mat[j][right]) == sum_val:
result.append([mat[i][left], mat[j][right]])
left += 1
right -= 1
else:
# two pointers moves
if (mat[i][left] + mat[j][right]) < sum_val:
left += 1
else:
right -= 1
return result
if __name__ == "__main__":
sum_val = 11
mat = [
[1, 3, 2, 4],
[5, 8, 7, 6],
[9, 10, 13, 11],
[12, 0, 14, 15]
]
result = pairSum(mat, sum_val)
for i in result:
print(f"({i[0]}, {i[1]})", end=", ")
//Driver Code Starts
using System;
using System.Collections.Generic;
//Driver Code Ends
class GfG
{
static List<List<int>> pairSum(int[][] mat, int sum)
{
int n = mat.Length;
List<List<int>> result = new List<List<int>>();
//sort all the rows
for (int i = 0; i < n; i++)
Array.Sort(mat[i]);
// select an element
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j < n; j++)
{
// use two pointers for other rows
int left = 0, right = mat[j].Length - 1;
while (left < mat[i].Length && right >= 0)
{
if ((mat[i][left] + mat[j][right]) == sum)
{
result.Add(new List<int> { mat[i][left], mat[j][right] });
left++;
right--;
}
else
{
// two pointers moves
if ((mat[i][left] + mat[j][right]) < sum)
left++;
else
right--;
}
}
}
}
return result;
}
//Driver Code Starts
static void Main()
{
int sum = 11;
int[][] mat = {
new int[]{1, 3, 2, 4},
new int[]{5, 8, 7, 6},
new int[]{9, 10, 13, 11},
new int[]{12, 0, 14, 15}
};
var result = pairSum(mat, sum);
foreach (var i in result)
{
Console.Write($"({i[0]}, {i[1]}), ");
}
}
}
//Driver Code Ends
function pairSum(mat, sum) {
let n = mat.length;
let result = [];
//sort all the rows
for (let i = 0; i < n; i++)
mat[i].sort((a, b) => a - b);
// select an element
for (let i = 0; i < n - 1; i++) {
for (let j = i + 1; j < n; j++) {
// use two pointers for other rows
let left = 0, right = mat[j].length - 1;
while (left < mat[i].length && right >= 0) {
if ((mat[i][left] + mat[j][right]) === sum) {
result.push([mat[i][left], mat[j][right]]);
left++;
right--;
} else {
// two pointers moves
if ((mat[i][left] + mat[j][right]) < sum)
left++;
else
right--;
}
}
}
}
return result;
}
//Driver Code Starts
// Driver code
let sum = 11;
let mat = [
[1, 3, 2, 4],
[5, 8, 7, 6],
[9, 10, 13, 11],
[12, 0, 14, 15]
];
let result = pairSum(mat, sum);
result.forEach(i => process.stdout.write(`(${i[0]}, ${i[1]}), `));
//Driver Code Ends
Output
(3, 8), (4, 7), (1, 10), (2, 9), (11, 0),
[Expected Approach] - Hashing - O(mn) Time and O(mn) Space
Store all matrix elements in a hash table along with their positions. Then traverse the matrix again and for each element, check if its required complement (sum − current value) exists in the hash table; if it exists and both elements belong to different rows, include the pair in the result.
//Driver Code Starts
#include <iostream>
#include<vector>
using namespace std;
//Driver Code Ends
vector<vector<int>> pairSum(vector<vector<int>>& mat, int sum) {
// use the hashset to store the elements
unordered_map<int, int> hash;
int n = mat.size();
vector<vector<int>>result;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
// required element
int remSum = sum - mat[i][j];
// find in the hash
auto it = hash.find(remSum);
// element found
if (it != hash.end()) {
int row = hash[remSum];
result.push_back({ mat[i][j],remSum});
}
hash[mat[i][j]] = i;
}
}
return result;
}
//Driver Code Starts
int main() {
int sum = 11;
vector<vector<int>> mat = {{1, 3, 2, 4},
{5, 8, 7, 6},
{9, 10, 13, 11},
{12, 0, 14, 15}};
vector<vector<int>>result=pairSum(mat, sum);
for(auto&i:result){
cout<<"(" <<i[0] << ", " <<i[1]<< "), ";
}
return 0;
}
//Driver Code Ends
//Driver Code Starts
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Arrays;
//Driver Code Ends
public class GfG{
static ArrayList<ArrayList<Integer>> pairSum(int[][] mat, int sum) {
// use the hashmap to store the elements
HashMap<Integer, Integer> hash = new HashMap<>();
int n = mat.length;
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
for (int i = 0; i < n; i++) {
for (int j = 0; j < mat[i].length; j++) {
// required element
int remSum = sum - mat[i][j];
// find in the hash
if (hash.containsKey(remSum)) {
result.add(new ArrayList<>(Arrays.asList(mat[i][j], remSum)));
}
hash.put(mat[i][j], i);
}
}
return result;
}
//Driver Code Starts
public static void main(String[] args) {
int sum = 11;
int[][] mat = {
{1, 3, 2, 4},
{5, 8, 7, 6},
{9, 10, 13, 11},
{12, 0, 14, 15}
};
ArrayList<ArrayList<Integer>> result = pairSum(mat, sum);
for (ArrayList<Integer> p : result) {
System.out.print("(" + p.get(0) + ", " + p.get(1) + "), ");
}
}
}
//Driver Code Ends
def pairSum(mat, sum_val):
# use the hashmap to store the elements
hash_map = {}
n = len(mat)
result = []
for i in range(n):
for j in range(len(mat[i])):
# required element
remSum = sum_val - mat[i][j]
# find in the hash
if remSum in hash_map:
result.append([mat[i][j], remSum])
hash_map[mat[i][j]] = i
return result
if __name__ =="__main__":
sum_val = 11
mat = [
[1, 3, 2, 4],
[5, 8, 7, 6],
[9, 10, 13, 11],
[12, 0, 14, 15]
]
result = pairSum(mat, sum_val)
for p in result:
print(f"({p[0]}, {p[1]})", end=", ")
//Driver Code Starts
using System;
using System.Collections.Generic;
//Driver Code Ends
class GfG
{
static List<List<int>> pairSum(int[][] mat, int sum)
{
// use the hashmap to store the elements
Dictionary<int, int> hash = new Dictionary<int, int>();
int n = mat.Length;
List<List<int>> result = new List<List<int>>();
for (int i = 0; i < n; i++)
{
for (int j = 0; j < mat[i].Length; j++)
{
// required element
int remSum = sum - mat[i][j];
// find in the hash
if (hash.ContainsKey(remSum))
{
result.Add(new List<int> { mat[i][j], remSum });
}
hash[mat[i][j]] = i;
}
}
return result;
}
//Driver Code Starts
static void Main()
{
int sum = 11;
int[][] mat = new int[][]
{
new int[] {1, 3, 2, 4},
new int[] {5, 8, 7, 6},
new int[] {9, 10, 13, 11},
new int[] {12, 0, 14, 15}
};
var result = pairSum(mat, sum);
foreach (var p in result)
{
Console.Write("(" + p[0] + ", " + p[1] + "), ");
}
}
}
//Driver Code Ends
function pairSum(mat, sum) {
// use the hashmap to store the elements
let hash = new Map();
let n = mat.length;
let result = [];
for (let i = 0; i < n; i++) {
for (let j = 0; j < mat[i].length; j++) {
// required element
let remSum = sum - mat[i][j];
// find in the hash
if (hash.has(remSum)) {
result.push([mat[i][j], remSum]);
}
hash.set(mat[i][j], i);
}
}
return result;
}
//Driver Code Starts
// Driver code
let sum = 11;
let mat = [
[1, 3, 2, 4],
[5, 8, 7, 6],
[9, 10, 13, 11],
[12, 0, 14, 15]
];
let result = pairSum(mat, sum);
result.forEach(p => process.stdout.write(`(${p[0]}, ${p[1]}), `));
//Driver Code Ends
Output
(8, 3), (7, 4), (9, 2), (10, 1), (0, 11),
Note: we traverse a matrix, a pair may be printed twice. To make sure that a pair is printed only once, we check if the row number of other elements picked from the hash table is more than the row number of the current element.