Check if any column has increasing elements in given range for Q queries

Given a matrix mat[][] of size N * M, and Q queries each of type {L, R} that denotes a range of row [L, R]. The task is to check if there is at least one column that has elements in increasing order in the given range of rows (i.e., is mat[L][j] ? mat[L+1][j] ? . . . ? mat[R][j] for any j).
Note: Here 1 based indexing is used.
Example:Â
Input: mat[][] = {{1, 2, 3, 5}, {3, 1, 3, 2}, {4, 5, 2, 3}, {5, 5, 3, 2}, {4, 4, 3, 4}}
Q = 6, queries[][] = {{1, 1}, {2, 5}, {3, 5}, {4, 5}, {1, 3}, {1, 5}}
Output:Â
YES
NOÂ
YES
YES
YESÂ
NO
Explanation: For the first query 1 element is always sorted.
For the second query, there is no column that is sorted.
For the 3rd query elements in 3rd columns are sorted.
For the 4th query elements in 3rd or 4th columns are sorted.
For the 5th query elements in first column are sorted.
For the 6th query there is no such columns which is sorted. Input: mat[][] = { {1, 2, 3, 4}, {2, 3, 4, 5}, {3, 4, 5, 6}, {4, 5, 6, 7 }}
Q = 5, queries[][] = { {1, 2}, {2, 3}, {3, 4}, {5, 6}, {7, 8}}
Output:Â
YES
YES
YES
NO
NOÂ
Approach: The problem can be solved using precomputation based on the following idea:
For each column, precalculate the maximum length of the maximum increasing subarray from 1st to ith row. Now while answering each query use the precomputed result to check if the elements in that range are increasing or not.
Follow the steps below to solve the problem:
- Initialize a matrix (say dp[][]) to store the result of precomputation.
- In order to precompute, calculate the maximum length of the maximum increasing subarray containing column elements till row i.
- Traverse in each column from j = 1 to M:
- If the element at ith row is at least the same as (i-1)th row increase then dp[i][j] = dp[i-1][j] + 1.
- Otherwise, dp[i][j] = 1.
- Traverse in each column from j = 1 to M:
- Initialize an array (say ans[]) to store the maximum length of increasing subarray finishing at ith row among all the columns.
- Iterate over the queries:
- If ans[r] for any query is at least same as the length of the range then a column exist which satisfies the given conditions.
- Otherwise, there is no such column.
Below is the implementation of the above approach.
C++14
// C++ code to implement the approachÂ
#include <bits/stdc++.h>using namespace std;Â
int dp[1005][1005];int ans[1005];Â
// Function to perform the precomputationvoid precompute(vector<int> a[], int N, int M){Â Â Â Â // For the first row length will always be 1Â Â Â Â for (int j = 0; j < M; j++)Â Â Â Â Â Â Â Â dp[j][0] = 1;Â
    // Loop to fill the dp[][] array    for (int i = 0; i < M; i++) {        for (int j = 1; j < N; j++) {Â
            // If element at the previous row is            // smaller or equal to current element            if (a[j][i] >= a[j - 1][i])                dp[i][j] = dp[i][j - 1] + 1;            else                dp[i][j] = 1;        }    }Â
    // Loop to fill the ans[] array    for (int i = 0; i < N; i++) {        for (int j = 0; j < M; j++) {            ans[i] = max(ans[i], dp[j][i]);        }    }}Â
// Function to solve the queriesvector<string> query(vector<int> a[],                     vector<int> arr[],                     int Q, int N, int M){    precompute(a, N, M);    vector<string> res;Â
    for (int i = 0; i < Q; i++) {        int l = arr[i][0];        int r = arr[i][1];        r--;        l--;Â
        // If maximum is greater than r-l+1        // then increasing sequence is possible        if (ans[r] >= r - l + 1)            res.push_back("YES");        else            res.push_back("NO");    }    return res;}Â
// Driver codeint main(){    int N = 5, M = 4;    vector<int> mat[N] = { { 1, 2, 3, 5 },                           { 3, 1, 3, 2 },                           { 4, 5, 2, 3 },                           { 5, 5, 3, 2 },                           { 4, 4, 3, 4 } };    int Q = 6;    vector<int> queries[Q]        = { { 1, 1 }, { 2, 5 }, { 3, 5 }, { 4, 5 }, { 1, 3 }, { 1, 5 } };Â
    // Function call    vector<string> sol        = query(mat, queries, Q, N, M);    for (auto s : sol)        cout << s << "\n";Â
    return 0;} |
Java
// Java code to implement the approachimport java.util.*;class GFG{Â
static int[][] dp = new int[1005][1005];static int[] ans = new int[1005];Â
// Function to perform the precomputationstatic void precompute(int[][] a, int N, int M){Â Â Â Â // For the first row length will always be 1Â Â Â Â for (int j = 0; j < M; j++)Â Â Â Â Â Â Â Â dp[j][0] = 1;Â
    // Loop to fill the dp[][] array    for (int i = 0; i < M; i++) {        for (int j = 1; j < N; j++) {Â
            // If element at the previous row is            // smaller or equal to current element            if (a[j][i] >= a[j - 1][i])                dp[i][j] = dp[i][j - 1] + 1;            else                dp[i][j] = 1;        }    }Â
    // Loop to fill the ans[] array    for (int i = 0; i < N; i++) {        for (int j = 0; j < M; j++) {            ans[i] = Math.max(ans[i], dp[j][i]);        }    }}Â
// Function to solve the queriesstatic ArrayList<String> query(int[][] a,                    int[][] arr,                    int Q, int N, int M){    precompute(a, N, M);    ArrayList<String> res = new ArrayList<String>();Â
    for (int i = 0; i < Q; i++) {        int l = arr[i][0];        int r = arr[i][1];        r--;        l--;Â
        // If maximum is greater than r-l+1        // then increasing sequence is possible        if (ans[r] >= r - l + 1)            res.add("YES");        else            res.add("NO");    }    return res;}Â
// Driver codepublic static void main(String[] args){    int N = 5, M = 4;    int[][] mat = { { 1, 2, 3, 5 },                        { 3, 1, 3, 2 },                        { 4, 5, 2, 3 },                        { 5, 5, 3, 2 },                        { 4, 4, 3, 4 } };    int Q = 6;    int[][] queries        = { { 1, 1 }, { 2, 5 }, { 3, 5 }, { 4, 5 }, { 1, 3 }, { 1, 5 } };Â
    // Function call    ArrayList<String> sol = query(mat, queries, Q, N, M) ;         for (String s : sol)        System.out.println(s);}}Â
// This code is contributed by Pushpesh Raj. |
Python3
# Python code to implement the approachdp = [[0 for x in range(1005)] for y in range(1005)]ans = [0]*1005Â
# Function to perform the precomputationdef precompute(a, N, M):Â Â Â Â # for the first row length will always be 1Â Â Â Â for j in range(M):Â Â Â Â Â Â Â Â dp[j][0] = 1Â
    # loop to fill the dp[][] array    for i in range(M):        for j in range(1, N):            # If element at the previous row is             # smaller or equal to current element            if(a[j][i] >= a[j-1][i]):                dp[i][j] = dp[i][j-1] + 1            else:                dp[i][j] = 1Â
    # loop to fill the ans[] array    for i in range(N):        for j in range(M):            ans[i] = max(ans[i], dp[j][i])Â
# function to solve the queriesdef query(a, arr, Q, N, M):    precompute(a, N, M)    res = []    for i in range(Q):        l = arr[i][0]        r = arr[i][1]        r -= 1        l -= 1        # If maximum is greater than r-l+1 then         # increasing sequence is possible        if(ans[r] >= r-l+1):            res.append("YES")        else:            res.append("NO")Â
    return resÂ
Â
N = 5M = 4mat = [[1, 2, 3, 5],       [3, 1, 3, 2],       [4, 5, 2, 3],       [5, 5, 3, 2],       [4, 4, 3, 4]]Q = 6queries = [[1, 1], [2, 5], [3, 5], [4, 5], [1, 3], [1, 5]]sol = query(mat, queries, Q, N, M)for s in range(len(sol)):    print(sol[s])Â
# This code is contributed by lokeshmvs21. |
C#
// C# code to implement the approachusing System;using System.Collections.Generic;Â
class Program {Â
    static int[, ] dp = new int[1005, 1005];    static int[] ans = new int[1005];Â
    // Function to perform the precomputation    static void precompute(int[, ] a, int N, int M)    {        // For the first row length will always be 1        for (int j = 0; j < M; j++)            dp[j, 0] = 1;Â
        // Loop to fill the dp[][] array        for (int i = 0; i < M; i++) {            for (int j = 1; j < N; j++) {Â
                // If element at the previous row is                // smaller or equal to current element                if (a[j, i] >= a[j - 1, i])                    dp[i, j] = dp[i, j - 1] + 1;                else                    dp[i, j] = 1;            }        }Â
        // Loop to fill the ans[] array        for (int i = 0; i < N; i++) {            for (int j = 0; j < M; j++) {Â
                ans[i] = Math.Max(ans[i], dp[j, i]);            }        }    }Â
    // Function to solve the queries    static List<string> query(int[, ] a, int[, ] arr, int Q,                              int N, int M)    {        precompute(a, N, M);        List<string> res = new List<string>();        for (int i = 0; i < Q; i++) {            int l = arr[i, 0];            int r = arr[i, 1];            r--;            l--;Â
            // If maximum is greater than r-l+1            // then increasing sequence is possible            if (ans[r] >= r - l + 1)                res.Add("YES");            else                res.Add("NO");        }        return res;    }    // Driver code    public static void Main()    {        int N = 5, M = 4;        int[, ] mat = { { 1, 2, 3, 5 },                        { 3, 1, 3, 2 },                        { 4, 5, 2, 3 },                        { 5, 5, 3, 2 },                        { 4, 4, 3, 4 } };        int Q = 6;        int[, ] queries = { { 1, 1 }, { 2, 5 }, { 3, 5 },                            { 4, 5 }, { 1, 3 }, { 1, 5 } };Â
        // Function call        List<string> sol = query(mat, queries, Q, N, M);        foreach(string s in sol) Console.WriteLine(s);    }}Â
// This code is contributed by Tapesh(tapeshdua420) |
Javascript
   // JavaScript code for the above approach   let dp = new Array(1005);   for (let i = 0; i < dp.length; i++) {     dp[i] = new Array(1005).fill(0);   }   let ans = new Array(1005).fill(0);Â
   // Function to perform the precomputation   function precompute(a, N, M)    {         // For the first row length will always be 1     for (let j = 0; j < M; j++)       dp[j][0] = 1;Â
     // Loop to fill the dp[][] array     for (let i = 0; i < M; i++) {       for (let j = 1; j < N; j++) {Â
         // If element at the previous row is         // smaller or equal to current element         if (a[j][i] >= a[j - 1][i])           dp[i][j] = dp[i][j - 1] + 1;         else           dp[i][j] = 1;       }     }Â
     // Loop to fill the ans[] array     for (let i = 0; i < N; i++) {       for (let j = 0; j < M; j++) {         ans[i] = Math.max(ans[i], dp[j][i]);       }     }     return ans;   }Â
   // Function to solve the queries   function query(a,     arr,     Q, N, M) {     ans = precompute(a, N, M);     let res = [];Â
     for (let i = 0; i < Q; i++) {       let l = arr[i][0];       let r = arr[i][1];       r--;       l--;Â
       // If maximum is greater than r-l+1       // then increasing sequence is possible       if (ans[r] >= r - l + 1)         res.push("YES");       else         res.push("NO");     }     return res;   }Â
   // Driver codeÂ
   let N = 5, M = 4;   let mat = [[1, 2, 3, 5],   [3, 1, 3, 2],   [4, 5, 2, 3],   [5, 5, 3, 2],   [4, 4, 3, 4]];   let Q = 6;   let queries     = [[1, 1], [2, 5], [3, 5], [4, 5], [1, 3], [1, 5]];Â
   // Function call   let sol     = query(mat, queries, Q, N, M);   for (let s of sol)     console.log(s + " ")Â
// This code is contributed by Potta Lokesh |
YES NO YES YES YES NO
Time Complexity: O(N*M + Q*M)
Auxiliary Space: O(N*M + N)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



