Queries to check whether a given digit is present in the given Range

Pre-requisites: Segment Tree Given an array of digits arr[]. Given a number of range [L, R] and a digit X with each range. The task is to check for each given range [L, R] whether the digit X is present within that range in the array arr[]. Examples:
Input : arr = [1, 3, 3, 9, 8, 7]
l1=0, r1=3, x=2 // Range 1
l1=2, r1=5, x=3 // Range 2
Output : NO
YES
For Range 1: The digit 2 is not present within
range [0, 3] in the array.
For Range 2: The digit 3 is present within the range
[2, 5] at index 2 in the given array.
Naive Approach: A naive approach is to traverse through each of the given range of the digits in the array and check whether the digit is present or not. Time Complexity: O(N) for each query. Better Approach: A better approach is to use Segment Tree. Since there are only 10 digits possible from (0-9), so each node of the segment tree will contain all the digits within the range of that node. We will use Set Data Structure at every node to store the digits. Set is a special data structure which removes redundant elements and store them in ascending order. We have used set data structure since it will be easier to merge 2 child nodes to get the parent node in the segment tree. We will insert all the digits present in the children nodes in the parent set and it will automatically remove the redundant digits. Hence at every set(node) there will be at max 10 elements (0-9 all the digits). Also there are inbuilt count function which returns the count of the element present in the set which will be helpful in the query function to check whether a digit is present at the node or not. If the count will be greater than 0 that means the element is present in the set we will return true else return false. Below is the implementation of the above approach:Â
C++
// CPP program to answer Queries to check whether// a given digit is present in the given rangeÂ
#include <bits/stdc++.h>using namespace std;Â
#define N 6Â
// Segment Tree with set at each nodeset<int> Tree[6 * N];Â
// Function to build the segment treevoid buildTree(int* arr, int idx, int s, int e){Â Â Â Â if (s == e) {Â Â Â Â Â Â Â Â Tree[idx].insert(arr[s]);Â Â Â Â Â Â Â Â return;Â Â Â Â }Â
    int mid = (s + e) >> 1;Â
    // Left child node    buildTree(arr, 2 * idx, s, mid);Â
    // Right child node    buildTree(arr, 2 * idx + 1, mid + 1, e);Â
    // Merging child nodes to get parent node.    // Since set is used, it will remove    // redundant digits.    for (auto it : Tree[2 * idx]) {        Tree[idx].insert(it);    }    for (auto it : Tree[2 * idx + 1]) {        Tree[idx].insert(it);    }}Â
// Function to query a rangebool query(int idx, int s, int e, int qs, int qe, int x){    // Complete Overlap condition    // return true if digit is present.    // else false.    if (qs <= s && e <= qe) {        if (Tree[idx].count(x) != 0) {            return true;        }        else            return false;    }Â
    // No Overlap condition    // Return false    if (qe < s || e < qs) {        return false;    }Â
    int mid = (s + e) >> 1;Â
    // If digit is found in any child    // return true, else False    bool LeftAns = query(2 * idx, s, mid, qs, qe, x);    bool RightAns = query(2 * idx + 1, mid + 1, e, qs, qe, x);Â
    return LeftAns or RightAns;}Â
// Driver Codeint main(){Â Â Â Â int arr[] = { 1, 3, 3, 9, 8, 7 };Â Â Â Â int n = sizeof(arr) / sizeof(arr[0]);Â
    // Build the tree    buildTree(arr, 1, 0, n - 1);Â
    int l, r, x;Â
    // Query 1    l = 0, r = 3, x = 2;    if (query(1, 0, n - 1, l, r, x))        cout << "YES" << '\n';    else        cout << "NO" << '\n';Â
    // Query 2    l = 2, r = 5, x = 3;    if (query(1, 0, n - 1, l, r, x))        cout << "YES" << '\n';    else        cout << "NO" << '\n';Â
    return 0;} |
Java
// Java program to answer Queries to check whether // a given digit is present in the given range import java.io.*;import java.util.*;Â
class GFG {Â Â Â Â static int N = 6;Â
    // Segment Tree with set at each node    @SuppressWarnings("unchecked")    static HashSet<Integer>[] Tree = new HashSet[6 * N];    static    {        for (int i = 0; i < 6 * N; i++)            Tree[i] = new HashSet<>();    }Â
    // Function to build the segment tree    static void buildTree(int[] arr, int idx, int s, int e)     {        if (s == e)         {            Tree[idx].add(arr[s]);            return;        }Â
        int mid = (s + e) / 2;Â
        // Left child node        buildTree(arr, 2 * idx, s, mid);Â
        // Right child node        buildTree(arr, 2 * idx + 1, mid + 1, e);Â
        // Merging child nodes to get parent node.        // Since set is used, it will remove        // redundant digits.        for (int it : Tree[2 * idx])            Tree[idx].add(it);        for (int it : Tree[2 * idx + 1])            Tree[idx].add(it);    }Â
    // Function to query a range    static boolean query(int idx, int s, int e,                        int qs, int qe, int x)     {Â
        // Complete Overlap condition        // return true if digit is present.        // else false.        if (qs <= s && e <= qe)        {            if (Collections.frequency(Tree[idx], x) != 0)                return true;            else                return false;        }Â
        // No Overlap condition        // Return false        if (qe < s || e < qs)            return false;Â
        int mid = (s + e) / 2;Â
        // If digit is found in any child        // return true, else False        boolean LeftAns = query(2 * idx, s, mid, qs, qe, x);        boolean RightAns = query(2 * idx + 1, mid + 1, e, qs, qe, x);Â
        return (LeftAns || RightAns);    }Â
    // Driver Code    public static void main(String[] args)    {Â
        int[] arr = { 1, 3, 3, 9, 8, 7 };        int n = arr.length;Â
        // Build the tree        buildTree(arr, 1, 0, n - 1);Â
        int l, r, x;Â
        // Query 1        l = 0;        r = 3;        x = 2;        if (query(1, 0, n - 1, l, r, x))            System.out.println("Yes");        else            System.out.println("No");Â
        // Query 2        l = 2;        r = 5;        x = 3;        if (query(1, 0, n - 1, l, r, x))            System.out.println("Yes");        else            System.out.println("No");    }}Â
// This code is contributed by// sanjeev2552 |
Python3
# Python3 program to answer Queries to check whether# a given digit is present in the given rangeN = 6Â
# Segment Tree with set at each nodeTree = [0] * (6 * N)for i in range(6 * N):Â Â Â Â Tree[i] = set()Â
# Function to build the segment treedef buildTree(arr: list, idx: int,                   s: int, e: int) -> None:    global Tree    if s == e:        Tree[idx].add(arr[s])        returnÂ
    mid = (s + e) // 2Â
    # Left child node    buildTree(arr, 2 * idx, s, mid)Â
    # Right child node    buildTree(arr, 2 * idx + 1, mid + 1, e)Â
    # Merging child nodes to get parent node.    # Since set is used, it will remove    # redundant digits.    for it in Tree[2 * idx]:        Tree[idx].add(it)Â
    for it in Tree[2 * idx + 1]:        Tree[idx].add(it)Â
# Function to query a rangedef query(idx: int, s: int, e: int, Â Â Â Â Â Â Â Â Â Â qs: int, qe: int, x: int) -> bool:Â Â Â Â global TreeÂ
    # Complete Overlap condition    # return true if digit is present.    # else false.    if qs <= s and e <= qe:        if list(Tree[idx]).count(x) != 0:            return True        else:            return FalseÂ
    # No Overlap condition    # Return false    if qe < s or e < qs:        return FalseÂ
    mid = (s + e) // 2Â
    # If digit is found in any child    # return true, else False    leftAns = query(2 * idx, s, mid, qs, qe, x)    rightAns = query(2 * idx + 1,                          mid + 1, e, qs, qe, x)Â
    return (leftAns or rightAns)Â
# Driver Codeif __name__ == "__main__":Â Â Â Â arr = [1, 3, 3, 9, 8, 7]Â Â Â Â n = len(arr)Â
    # Build the tree    buildTree(arr, 1, 0, n - 1)Â
    # Query 1    l = 0    r = 3    x = 2    if query(1, 0, n - 1, l, r, x):        print("YES")    else:        print("NO")Â
    # Query 2    l = 2    r = 5    x = 3    if query(1, 0, n - 1, l, r, x):        print("YES")    else:        print("NO")Â
# This code is contributed by# sanjeev2552 |
C#
// C# program to answer Queries to check whether // a given digit is present in the given range using System;using System.Collections.Generic;Â
class GFG {Â Â Â Â static int N = 6;Â
    // Segment Tree with set at each node    static SortedSet<int>[] Tree = new SortedSet<int>[6 * N];Â
    // Function to build the segment tree    static void buildTree(int[] arr, int idx, int s, int e)     {        if (s == e)         {            Tree[idx].Add(arr[s]);            return;        }Â
        int mid = (s + e) / 2;Â
        // Left child node        buildTree(arr, 2 * idx, s, mid);Â
        // Right child node        buildTree(arr, 2 * idx + 1, mid + 1, e);Â
        // Merging child nodes to get parent node.        // Since set is used, it will remove        // redundant digits.        foreach (int it in Tree[2 * idx])            Tree[idx].Add(it);        foreach (int it in Tree[2 * idx + 1])            Tree[idx].Add(it);    }Â
    // Function to query a range    static bool query(int idx, int s, int e,                        int qs, int qe, int x)     {Â
        // Complete Overlap condition        // return true if digit is present.        // else false.        if (qs <= s && e <= qe)        {            if (Tree[idx].Contains(x))                return true;            else                return false;        }Â
        // No Overlap condition        // Return false        if (qe < s || e < qs)            return false;Â
        int mid = (s + e) / 2;Â
        // If digit is found in any child        // return true, else False        bool LeftAns = query(2 * idx, s, mid, qs, qe, x);        bool RightAns = query(2 * idx + 1, mid + 1, e, qs, qe, x);Â
        return (LeftAns || RightAns);    }Â
    // Driver Code    public static void Main(String[] args)    {Â
        int[] arr = { 1, 3, 3, 9, 8, 7 };        int n = arr.Length;        for (int i = 0; i < 6 * N; i++)            Tree[i] = new SortedSet<int>();                 // Build the tree        buildTree(arr, 1, 0, n - 1);Â
        int l, r, x;Â
        // Query 1        l = 0;        r = 3;        x = 2;        if (query(1, 0, n - 1, l, r, x))            Console.WriteLine("Yes");        else            Console.WriteLine("No");Â
        // Query 2        l = 2;        r = 5;        x = 3;        if (query(1, 0, n - 1, l, r, x))            Console.WriteLine("Yes");        else            Console.WriteLine("No");    }}Â
// This code is contributed by Rajput-Ji |
Javascript
// JavaScript program to answer Queries to check whether// a given digit is present in the given rangeÂ
const N = 6;Â
// Segment Tree with set at each nodelet Tree = new Array(6 * N);for (let i = 0; i < 6 * N; i++) {Tree[i] = new Set();}Â
// Function to build the segment treefunction buildTree(arr, idx, s, e) {if (s == e) {Tree[idx].add(arr[s]);return;}Â
Â
let mid = Math.floor((s + e) / 2);Â
// Left child nodebuildTree(arr, 2 * idx, s, mid);Â
// Right child nodebuildTree(arr, 2 * idx + 1, mid + 1, e);Â
// Merging child nodes to get parent node.// Since set is used, it will remove// redundant digits.for (let it of Tree[2 * idx]) {Â Â Â Â Tree[idx].add(it);}Â
for (let it of Tree[2 * idx + 1]) {Â Â Â Â Tree[idx].add(it);}}Â
// Function to query a rangefunction query(idx, s, e, qs, qe, x){Â
// Complete Overlap condition// return true if digit is present.// else false.if (qs <= s && e <= qe) {if ([...Tree[idx]].filter(item => item == x).length != 0) {return true;} else {return false;}}Â
// No Overlap condition// Return falseif (qe < s || e < qs) {Â Â Â Â return false;}Â
let mid = Math.floor((s + e) / 2);Â
// If digit is found in any child// return true, else Falselet leftAns = query(2 * idx, s, mid, qs, qe, x);let rightAns = query(2 * idx + 1, mid + 1, e, qs, qe, x);Â
return (leftAns || rightAns);}Â
// Driver Codelet arr = [1, 3, 3, 9, 8, 7];let n = arr.length;Â
// Build the treebuildTree(arr, 1, 0, n - 1);Â
// Query 1let l = 0;let r = 3;let x = 2;if (query(1, 0, n - 1, l, r, x)) {console.log("YES");} else {console.log("NO");}Â
// Query 2l = 2;r = 5;x = 3;if (query(1, 0, n - 1, l, r, x)) {console.log("YES");} else {console.log("NO");} |
NO YES
Time Complexity: O(N) once for building the segment tree, then O(logN) for each query.
Auxiliary Space: O(N)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



