Open In App

Fill the Matrix by following the given conditions

Last Updated : 04 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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:

C++




#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




// 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




# 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)


C#




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);
    }
}


Javascript




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);


Output

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)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads