Check if every row in given Matrix contains all the integers from 1 to N


A matrix is a two-dimensional data structure made up of rows and columns set out like a grid of squares. Grids, multidimensional arrays, and tabular data are frequently represented using it.

Problem Statement

We are given a matrix of dimensions and the task is to check whether each row of the matrix consists of every number from 1 to n. The order of the numbers in the row do not matter. Return true if this statement holds true else return false.

For Example

Input: mtx = [[1,2,3],[3,2,1],[2,1,3]]
Output: True

Explanation

We are given a matrix mtx of size 3*3. In order to return true, each of the 3 i.e. n rows must contain all the numbers from 1 to 3 i.e. 1 to m. This condition holds true since each row contains the numbers 1,2, and 3.

For Example

Input: mtx = [[2,1],[1,1]]
Output: False

Explanation

The first row satisfies the condition that each row should contain digits from [1,m]. In this case m = 2. However in the second row, the number 2 does not occur and instead the number 1 repeats itself. This is a violation to the primary condition. Hence the program is expected to return a false.

For Example

Input: mtx = [[2]]
Output: False

Explanation

The matrix mtx consists of 1 row and 1 column only. The row is expected to consist of the number 1 which is not the case here hence the program is expected to return a false;

Solution Approach 1

The problem statement consists has one primary condition that is as follows −

  • Each of the n rows of the matrix of size n * m must contain all digits from [1,m].

  • Therefore, an intuitive and bruteforce solution is to iterate over all the rows and sort the elements of the current row. We follow this up by checking that the element at every column in that row is one greater than the column index.

  • If this holds correct for all the rows, we return true. Else we return a false.

  • Since we are iterating over all the elements of the matrix mtx and also sorting every row, the program is expected to run in (m*n*logn) time.

Pseudocode

  • Start

  • Initialize matrix mtx of size n*m.

  • Traverse each row of the matrix, and sort it

  • Traverse each element of the row to check if the current element is 1 greater than the current column index.

  • If at any point the previous condition does not hold true, return a false

  • Return a true otherwise

  • Stop

Algorithm

  • Initialize vector<vector<int>>mtx

  • for (i : 0 to n - 1)

    • sort(mtx[i])

    • for (j : 0 to m - 1)

      • if (mtx[i][j] != j + 1)

      • return false

  • return true

Example: C++ Program Code

The following C++ code checks whether each row of the provided matrix contains all of the integers from 1 to m and prints true or false accordingly.

// C++ program to verify that each row of the provided matrix contains all of the integers from 1 to m.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// main function
int main(){
   vector<vector<int>>mtx = {{1,2,3},{2,1,3},{3,2,1}};
   int n = mtx.size();
   int m = mtx[0].size();
   for (int i = 0; i < n; i++){
      sort(mtx[i].begin(), mtx[i].end());
      for (int j = 0; j < m; j++){
         if (mtx[i][j] != j + 1){
            cout << "false";
            return 0;
         }
      }
   }
   cout << "true";
   return 0;
}

Output

True

Time and Space Complexity Analysis

The program runs in O(n*logn*m) time complexity and does not require any auxiliary space.

Solution Approach 2

To make the above approach more efficient in terms of time complexity. We use the condition that the elements in the row are in the range [1, m]. So, instead of sorting each row we skip sorting and perform the following steps.

  • While iterating over the row, make the element at position mtx[i][current_element - 1] is negative.

  • If all negative integers are present in the matrix after this operation has been performed on each element, then all rows should have the numbers from 1 to m. and we return true.

  • Else we return false.

Pseudocode

  • Start

  • Initialize matrix mtx of size n*m.

  • Traverse each row

  • For each element in the current row, make the element at position mtx[row][element] negative.

  • If that element was already negative, return false

  • After making all the elements negative return true

Algorithm

  • Initialize vector<vector<int>>mtx

  • for (i : 0 to n - 1)

    • for (j : 0 to m - 1)

      • if (mtx[i][mtx[i][j] - 1] < 0)

        • return false

      • mtx[i][mtx[i][j] - 1] = -mtx[i][mtx[i][j] - 1];

  • return true

Example: C++ Program Code

The following C++ code verifies whether each row of the matrix contains all the digits from 1 to m where m is the number of columns in the matrix. We exploit the fact that the m columns contain numbers from 1 to m only. For every row, we mark the element at index equal to value of current element - 1 (since 0-based indexing is used) as negative to indicate that it has been visited previously. This would imply the existence of duplicates which further implies that the matrix is not valid as it does not contain all the numbers from 1 to m. In that case we return false. Else we return true.

// C++ program to verify that each row of the provided matrix contains all of the integers from 1 to m.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// main function
int main(){
   vector<vector<int>> mtx = {{1, 2, 3}, {3, 1, 2}, {2, 1, 3}};
   int n = mtx.size();
   int m = mtx[0].size();
   // Iterate over each row of the matrix
   for (int i = 0; i < n; i++){
      // Iterate over each element in the row
      for (int j = 0; j < m; j++){
         // if the element is already negative that means there is repetition which should not been possible if all numbers from 1 to m are present
         if (mtx[i][mtx[i][j] - 1] < 0){
            cout << "false";
            return 0;
         }
         // Mark the element as visited by making it negative
         mtx[i][abs(mtx[i][j]) - 1] = -mtx[i][abs(mtx[i][j]) - 1];
      }
   }
   // If all elements are visited without encountering a repetition, the matrix is valid
   cout << "true";
   return 0;
}

Output

True

Time Complexity: O(n*m) − The time complexity of the code is O(n * m), where n is the number of rows in the matrix and m is the number of columns.

The code uses nested loops to iterate over each element of the matrix. The outer loop iterates n times, and the inner loop iterates m times. Therefore, the total number of iterations is n * m.

Auxiliary Space: O(1) − The program makes use of variables which take up constant extra space.

Conclusion

The article discusses a naive and an efficient approach to verify that each row of the provided matrix contains all of the integers from 1 to m. The solution approaches consist of the pseudocode, algorithm, C++ program and time and space complexity analysis for a deeper understanding.

Updated on: 25-Oct-2023

37 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements