Open in App
Not now

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

• Last Updated : 28 Nov, 2022

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.
• 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 precomputation
void 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 queries
vector<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 code
int 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 approach
import java.util.*;
class GFG{

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 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)
else
}
return res;
}

// Driver code
public 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 approach
dp = [[0 for x in range(1005)] for y in range(1005)]
ans = [0]*1005

# Function to perform the precomputation
def 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 queries
def 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 = 5
M = 4
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]]
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 approach
using 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)
else
}
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
Output

YES
NO
YES
YES
YES
NO

Time Complexity: O(N*M + Q*M)
Auxiliary Space: O(N*M + N)

My Personal Notes arrow_drop_up
Related Articles