Given a matrix A[][] of N rows and M columns. Some of the elements of the matrix are -1, which denotes that cell is empty. Then your task is to check if it is possible to fill empty cells in such a way that each row and column is sorted. If yes, then output matrix after filling cells, else output -1. If there are multiple solutions, then print any of them.
Examples:
Input: N = 4, M = 4, A[][] = {{1, 2, 2, 3}, {1, -1, 7, -1}, {6, -1, -1, -1}, {-1, -1, -1, -1}}
Output: One possible solution can be: A = {1, 2, 2, 3}, {1, 7, 7, 100}, {6, 10, 20, 101}, {7, 11, 21, 20000}}
Explanation: The cells are filled with appropriate values, Each row and column is sorted.Input: N = 2, M = 3, A[][] = {{1, 4, -1}, {1, -1, 3}}
Output: -1
Explanation: It can be verified that it is not possible to fill all empty cells following the given condition.
Approach: Implement the idea below to solve the problem
The problem is based on the observation. It can be solved easily if one has a good observations skill. Let us discuss ow to solve this problem:
- We must start filling the first row from left to right. If a cell is -1, we have to fill it with the value of the cell to its left. If it’s the very first cell, fill it with 1.
- For each subsequent row, we will fill each cell from left to right. If a cell is -1, we fill it with the maximum of the value in the cell above it and the cell to its left.
- Checking Validity: After filling all cells, We need to check, if each row and column of the matrix is increasing (i.e. values don’t decrease as you move right in a row or down in a column). If they do decrease, it means he can’t fill up the matrix as required.
- Output: If all rows and columns are increasing, We will print out filled matrix. If not, then print -1 to indicate that it’s not possible to fill the matrix as required.
Steps were taken to solve the problem:
- Traverse the first row from left to right. If a cell is -1, replace it with the value of the cell to its left. If it’s the very first cell, replace it with 1.
- For each subsequent row, traverse each cell from left to right. If a cell is -1, replace it with the maximum of the value in the cell above it and the cell to its left.
- After filling all cells, check if each row and column of the matrix is non-decreasing (i.e., values don’t decrease as you move right in a row or down in a column). If they do decrease, it means it’s not possible to fill up the matrix as required.
- If all rows and columns are increasing, print out the filled matrix. If not, print -1 to indicate that it’s not possible to fill the matrix as required.
Code to implement the approach:
#include <iostream> #include <vector> using namespace std;
// Method to check if it is possible to // fill empty cells or not void Check_possibility( int N, int M, vector<vector< int >>& arr) {
// Restore the first row of the matrix
for ( int i = 0; i < M; i++) {
if (i == 0) {
arr[0][i] = (arr[0][i] == -1) ? 1 : arr[0][i];
} else {
arr[0][i] = (arr[0][i] == -1) ? arr[0][i - 1] : arr[0][i];
}
}
// Restore the subsequent rows of the matrix
for ( int i = 1; i < N; i++) {
for ( int j = 0; j < M; j++) {
if (j == 0) {
arr[i][j] = (arr[i][j] == -1) ? arr[i - 1][j] : arr[i][j];
} else {
int max_val = max(arr[i - 1][j], arr[i][j - 1]);
arr[i][j] = (arr[i][j] == -1) ? max_val : arr[i][j];
}
}
}
// Check if each row of the matrix is non-decreasing
for ( int i = 0; i < N; i++) {
for ( int j = 1; j < M; j++) {
if (arr[i][j] < arr[i][j - 1]) {
cout << -1 << endl;
return ;
}
}
}
// Check if each column of the matrix is non-decreasing
for ( int i = 0; i < M; i++) {
for ( int j = 1; j < N; j++) {
if (arr[j][i] < arr[j - 1][i]) {
cout << -1 << endl;
return ;
}
}
}
// Print the restored matrix
for ( int i = 0; i < N; i++) {
for ( int j = 0; j < M; j++) {
cout << arr[i][j] << " " ;
}
cout << endl;
}
} int main() {
int N = 4;
int M = 4;
vector<vector< int >> A = {
{1, 2, 2, 3},
{1, -1, 7, -1},
{6, -1, -1, -1},
{-1, -1, -1, -1}
};
// Function call
Check_possibility(N, M, A);
return 0;
} |
// Java code to implement the approach import java.util.*;
class Main {
public static void main(String[] args)
{
// Inputs
int N = 4 ;
int M = 4 ;
int [][] A = { { 1 , 2 , 2 , 3 },
{ 1 , - 1 , 7 , - 1 },
{ 6 , - 1 , - 1 , - 1 },
{ - 1 , - 1 , - 1 , - 1 } };
// Function call
Check_possiblity(N, M, A);
}
// Method to check if it is possible to
// Fill empty cells or not
public static void Check_possiblity( int N, int M,
int [][] arr)
{
// Restore the first row of the matrix
for ( int i = 0 ; i < M; i++) {
if (i == 0 ) {
arr[ 0 ][i] = arr[ 0 ][i] == - 1 ? 1 : arr[ 0 ][i];
}
else {
arr[ 0 ][i] = arr[ 0 ][i] == - 1 ? arr[ 0 ][i - 1 ]
: arr[ 0 ][i];
}
}
// Restore the subsequent
// rows of the matrix
for ( int i = 1 ; i < N; i++) {
for ( int j = 0 ; j < M; j++) {
if (j == 0 ) {
arr[i][j] = arr[i][j] == - 1
? arr[i - 1 ][j]
: arr[i][j];
}
else {
int max = Math.max(arr[i - 1 ][j],
arr[i][j - 1 ]);
arr[i][j]
= arr[i][j] == - 1 ? max : arr[i][j];
}
}
}
// Check if each row of the matrix
// is non-decreasing
for ( int i = 0 ; i < N; i++) {
for ( int j = 1 ; j < M; j++) {
if (arr[i][j] < arr[i][j - 1 ]) {
System.out.println(- 1 );
return ;
}
}
}
// Check if each column of the
// matrix is non-decreasing
for ( int i = 0 ; i < M; i++) {
for ( int j = 1 ; j < N; j++) {
if (arr[j][i] < arr[j - 1 ][i]) {
System.out.println(- 1 );
return ;
}
}
}
// Print the restored matrix
for ( int i = 0 ; i < N; i++) {
for ( int j = 0 ; j < M; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
} |
# Python code to implement the above approach # Function to check if it is possible to fill empty cells or not def check_possibility(N, M, arr):
# Restore the first row of the matrix
for i in range (M):
if i = = 0 :
arr[ 0 ][i] = 1 if arr[ 0 ][i] = = - 1 else arr[ 0 ][i]
else :
arr[ 0 ][i] = arr[ 0 ][i - 1 ] if arr[ 0 ][i] = = - 1 else arr[ 0 ][i]
# Restore the subsequent rows of the matrix
for i in range ( 1 , N):
for j in range (M):
if j = = 0 :
arr[i][j] = arr[i - 1 ][j] if arr[i][j] = = - 1 else arr[i][j]
else :
max_val = max (arr[i - 1 ][j], arr[i][j - 1 ])
arr[i][j] = max_val if arr[i][j] = = - 1 else arr[i][j]
# Check if each row of the matrix is non-decreasing
for i in range (N):
for j in range ( 1 , M):
if arr[i][j] < arr[i][j - 1 ]:
print ( - 1 )
return
# Check if each column of the matrix is non-decreasing
for i in range (M):
for j in range ( 1 , N):
if arr[j][i] < arr[j - 1 ][i]:
print ( - 1 )
return
# Print the restored matrix
for i in range (N):
print ( " " .join( map ( str , arr[i])))
# Driver code if __name__ = = "__main__" :
N = 4
M = 4
A = [
[ 1 , 2 , 2 , 3 ],
[ 1 , - 1 , 7 , - 1 ],
[ 6 , - 1 , - 1 , - 1 ],
[ - 1 , - 1 , - 1 , - 1 ]
]
# Function call
check_possibility(N, M, A)
# This code is contributed by Abhinav Mahajan (abhinav_m22) |
using System;
using System.Collections.Generic;
class Program
{ // Method to check if it is possible to
// fill empty cells or not
static void CheckPossibility( int N, int M, List<List< int >> arr)
{
// Restore the first row of the matrix
for ( int i = 0; i < M; i++)
{
if (i == 0)
{
arr[0][i] = (arr[0][i] == -1) ? 1 : arr[0][i];
}
else
{
arr[0][i] = (arr[0][i] == -1) ? arr[0][i - 1] : arr[0][i];
}
}
// Restore the subsequent rows of the matrix
for ( int i = 1; i < N; i++)
{
for ( int j = 0; j < M; j++)
{
if (j == 0)
{
arr[i][j] = (arr[i][j] == -1) ? arr[i - 1][j] : arr[i][j];
}
else
{
int maxVal = Math.Max(arr[i - 1][j], arr[i][j - 1]);
arr[i][j] = (arr[i][j] == -1) ? maxVal : arr[i][j];
}
}
}
// Check if each row of the matrix is non-decreasing
for ( int i = 0; i < N; i++)
{
for ( int j = 1; j < M; j++)
{
if (arr[i][j] < arr[i][j - 1])
{
Console.WriteLine(-1);
return ;
}
}
}
// Check if each column of the matrix is non-decreasing
for ( int i = 0; i < M; i++)
{
for ( int j = 1; j < N; j++)
{
if (arr[j][i] < arr[j - 1][i])
{
Console.WriteLine(-1);
return ;
}
}
}
// Print the restored matrix
for ( int i = 0; i < N; i++)
{
for ( int j = 0; j < M; j++)
{
Console.Write(arr[i][j] + " " );
}
Console.WriteLine();
}
}
static void Main( string [] args)
{
int N = 4;
int M = 4;
List<List< int >> A = new List<List< int >>()
{
new List< int > { 1, 2, 2, 3 },
new List< int > { 1, -1, 7, -1 },
new List< int > { 6, -1, -1, -1 },
new List< int > { -1, -1, -1, -1 }
};
// Function call
CheckPossibility(N, M, A);
}
} |
function checkPossibility(N, M, arr) {
// Restore the first row of the matrix
for (let i = 0; i < M; i++) {
if (i === 0) {
arr[0][i] = (arr[0][i] === -1) ? 1 : arr[0][i];
} else {
arr[0][i] = (arr[0][i] === -1) ? arr[0][i - 1] : arr[0][i];
}
}
// Restore the subsequent rows of the matrix
for (let i = 1; i < N; i++) {
for (let j = 0; j < M; j++) {
if (j === 0) {
arr[i][j] = (arr[i][j] === -1) ? arr[i - 1][j] : arr[i][j];
} else {
const max_val = Math.max(arr[i - 1][j], arr[i][j - 1]);
arr[i][j] = (arr[i][j] === -1) ? max_val : arr[i][j];
}
}
}
// Check if each row of the matrix is non-decreasing
for (let i = 0; i < N; i++) {
for (let j = 1; j < M; j++) {
if (arr[i][j] < arr[i][j - 1]) {
console.log(-1);
return ;
}
}
}
// Check if each column of the matrix is non-decreasing
for (let i = 0; i < M; i++) {
for (let j = 1; j < N; j++) {
if (arr[j][i] < arr[j - 1][i]) {
console.log(-1);
return ;
}
}
}
// Print the restored matrix
for (let i = 0; i < N; i++) {
for (let j = 0; j < M; j++) {
console.log(arr[i][j] + " " );
}
console.log();
}
} // Driver code const N = 4; const M = 4; const A = [ [1, 2, 2, 3],
[1, -1, 7, -1],
[6, -1, -1, -1],
[-1, -1, -1, -1]
]; // Function call checkPossibility(N, M, A); |
1 2 2 3 1 2 7 7 6 6 7 7 6 6 7 7
Time Complexity: O(N*M)
Auxiliary Space: O(1)