📜  打印下一个更大数量的 Q 查询

📅  最后修改于: 2022-05-13 01:57:09.114000             🧑  作者: Mango

打印下一个更大数量的 Q 查询

给定一个包含 n 个元素和 q 个查询的数组,对于每个索引为 i 的查询,找到下一个更大的元素并打印它的值。如果它的右边没有更大的元素,则打印-1。
例子:

Input : arr[] = {3, 4, 2, 7, 5, 8, 10, 6} 
        query indexes = {3, 6, 1}
Output: 8 -1 7 
Explanation : 
For the 1st query index is 3, element is 7 and 
the next greater element at its right is 8 

For the 2nd query index is 6, element is 10 and 
there is no element greater then 10 at right, 
so print -1.

For the 3rd query index is 1, element is 4 and
the next greater element at its right is 7.

正常方法:正常方法是让每个查询在循环中从索引移动到 n 并找出下一个更大的元素并打印它,但在最坏的情况下这将需要 n 次迭代,如果查询的数量很多很高。
时间复杂度:O(n^2)
辅助空间>:O(1)
有效的方法:
一种有效的方法是基于下一个更大的元素。我们将下一个更大元素的索引存储在一个数组中,并且对于每个查询过程,在O(1)中回答查询,这将提高效率。
但是要找出数组中每个索引的下一个更大的元素,有两种方法。
一个将占用o(n^2)O(n)空间,这将从 I+1 迭代到 n 索引 I 处的每个元素,并找出下一个更大的元素并存储它。
但更有效的方法是使用堆栈,我们使用索引来比较并在 next[] 中存储下一个更大的元素索引。
1)将第一个索引压入堆栈。
2)一一选择其余索引,然后循环执行以下步骤。
....a) 将当前元素标记为 i。
....b) 如果堆栈不为空,则从堆栈中弹出一个索引并将 a[index] 与 a[I] 进行比较。
....c) 如果 a[I] 大于 a[index],则 a[I] 是 a[index] 的下一个更大元素。
....d) 当弹出的索引元素小于 a[I] 时,继续从堆栈中弹出。 a[I] 成为所有此类弹出元素的下一个更大元素
....g) 如果 a[I] 小于弹出的索引元素,则将弹出的索引推回。
3) 步骤 2 中的循环结束后,从堆栈中弹出所有索引并打印 -1 作为它们的下一个索引。

C++
// C++ program to print
// next greater number
// of Q queries
#include 
using namespace std;
 
// array to store the next
// greater element index
void next_greatest(int next[],
                   int a[], int n)
{
    // use of stl
    // stack in c++
    stack s;
 
    // push the 0th
    // index to the stack
    s.push(0);
 
    // traverse in the
    // loop from 1-nth index
    for (int i = 1; i < n; i++)
    {
 
        // iterate till loop is empty
        while (!s.empty()) {
 
            // get the topmost
            // index in the stack
            int cur = s.top();
 
            // if the current element is 
            // greater then the top indexth
            // element, then this will be
            // the next greatest index
            // of the top indexth element
            if (a[cur] < a[i])
            {
                 
                // initialise the cur
                // index position's
                // next greatest as index
                next[cur] = i;
 
                // pop the cur index
                // as its greater
                // element has been found
                s.pop();
            }
 
            // if not greater
            // then break
            else
                break;
        }
        // push the i index so that its
        // next greatest can be found
        s.push(i);
    }
 
    // iterate for all other
    // index left inside stack
    while (!s.empty())
    {
        int cur = s.top();
 
        // mark it as -1 as no
        // element in greater
        // then it in right
        next[cur] = -1;
 
        s.pop();
    }
}
 
// answers all
// queries in O(1)
int answer_query(int a[], int next[],
                 int n, int index)
{
    // stores the next greater
    // element positions
    int position = next[index];
 
    // if position is -1 then no
    // greater element is at right.
    if (position == -1)
        return -1;
 
    // if there is a index that
    // has greater element
    // at right then return its
    // value as a[position]
    else
        return a[position];
}
 
// Driver Code
int main()
{
 
    int a[] = {3, 4, 2, 7,
               5, 8, 10, 6 };
 
    int n = sizeof(a) / sizeof(a[0]);
 
    // initializes the
    // next array as 0
    int next[n] = { 0 };
 
    // calls the function
    // to pre-calculate
    // the next greatest
    // element indexes
    next_greatest(next, a, n);
 
    // query 1 answered
    cout << answer_query(a, next, n, 3) << " ";
 
    // query 2 answered
    cout << answer_query(a, next, n, 6) << " ";
 
    // query 3 answered
    cout << answer_query(a, next, n, 1) << " ";
}


Java
// Java program to print
// next greater number
// of Q queries
import java.util.*;
 
class GFG
{
public static int[] query(int arr[],
                          int query[])
{
    int ans[] = new int[arr.length];// this array contains
                                    // the next greatest
                                    // elements of all the elements
    Stack s = new Stack<>();
    // push the 0th index
    // to the stack
    s.push(arr[0]);
    int j = 0;
    //traverse rest
    // of the array
    for(int i = 1; i < arr.length; i++)
    {
        int next = arr[i];
         
        if(!s.isEmpty())
        {
            // get the topmost
            // element in the stack
            int element = s.pop();
             
            /* If the popped element
            is smaller than next,
            then a) store the pair
            b) keep popping while
            elements are smaller and
            stack is not empty */
            while(next > element)
            {
                ans[j] = next;
                j++;
                if(s.isEmpty())
                    break;
                element = s.pop();
            }
             
            /* If element is greater
            than next, then
            push the element back */
            if (element > next)
                s.push(element);
        }
        /* push next to stack so
        that we can find next
        greater for it */
        s.push(next);
    }
    /* After iterating over the
    loop, the remaining elements
    in stack do not have the next
    greater element, so -1 for them */
    while(!s.isEmpty())
    {
        int element = s.pop();
        ans[j] = -1;
        j++;
    }
     
    // return the next
    // greatest array
    return ans;
}
 
// Driver Code   
public static void main(String[] args)
{
    int arr[] = {3, 4, 2, 7,
                 5, 8, 10, 6};
    int query[] = {3, 6, 1};
    int ans[] = query(arr,query);
     
    // getting output array
    // with next greatest elements
    for(int i = 0; i < query.length; i++)
    {
        // displaying the next greater
        // element for given set of queries
        System.out.print(ans[query[i]] + " ");
    }
}
}
 
// This code was contributed
// by Harshit Sood


Python3
# Python3 program to print
# next greater number
# of Q queries
 
# array to store the next
# greater element index
def next_greatest(next, a, n):
 
    # use of stl
    # stack in c++
    s = []
 
    # push the 0th
    # index to the stack
    s.append(0);
 
    # traverse in the
    # loop from 1-nth index
    for  i in range(1, n):
 
        # iterate till loop is empty
        while (len(s) != 0):
 
            # get the topmost
            # index in the stack
            cur = s[-1]
 
            # if the current element is 
            # greater then the top indexth
            # element, then this will be
            # the next greatest index
            # of the top indexth element
            if (a[cur] < a[i]):
                 
                # initialise the cur
                # index position's
                # next greatest as index
                next[cur] = i;
 
                # pop the cur index
                # as its greater
                # element has been found
                s.pop();
 
            # if not greater
            # then break
            else:
                break;
         
        # push the i index so that its
        # next greatest can be found
        s.append(i);
 
    # iterate for all other
    # index left inside stack
    while(len(s) != 0):
        cur = s[-1]
 
        # mark it as -1 as no
        # element in greater
        # then it in right
        next[cur] = -1;
        s.pop();
     
# answers all
# queries in O(1)
def answer_query(a, next, n, index):
 
    # stores the next greater
    # element positions
    position = next[index];
 
    # if position is -1 then no
    # greater element is at right.
    if(position == -1):
        return -1;
 
    # if there is a index that
    # has greater element
    # at right then return its
    # value as a[position]
    else:
        return a[position];
 
# Driver Code
if __name__=='__main__':
 
    a = [3, 4, 2, 7, 5, 8, 10, 6 ]
    n = len(a)
 
    # initializes the
    # next array as 0
    next=[0 for i in range(n)]
 
    # calls the function
    # to pre-calculate
    # the next greatest
    # element indexes
    next_greatest(next, a, n);
 
    # query 1 answered
    print(answer_query(a, next, n, 3), end = ' ')
 
    # query 2 answered
    print(answer_query(a, next, n, 6), end = ' ')
 
    # query 3 answered
    print(answer_query(a, next, n, 1), end = ' ')
 
# This code is contributed by rutvik_56.


C#
// C# program to print next greater
// number of Q queries
using System;
using System.Collections.Generic;
 
class GFG
{
public static int[] query(int[] arr,
                          int[] query)
{
    int[] ans = new int[arr.Length]; // this array contains
                                     // the next greatest
                                     // elements of all the elements
    Stack s = new Stack();
     
    // push the 0th index to the stack
    s.Push(arr[0]);
    int j = 0;
     
    // traverse rest of the array
    for (int i = 1; i < arr.Length; i++)
    {
        int next = arr[i];
 
        if (s.Count > 0)
        {
            // get the topmost element in the stack
            int element = s.Pop();
 
            /* If the popped element is smaller
            than next, then
            a) store the pair
            b) keep popping while
            elements are smaller and
            stack is not empty */
            while (next > element)
            {
                ans[j] = next;
                j++;
                if (s.Count == 0)
                {
                    break;
                }
                element = s.Pop();
            }
 
            /* If element is greater
            than next, then
            push the element back */
            if (element > next)
            {
                s.Push(element);
            }
        }
        /* push next to stack so that we
        can find next greater for it */
        s.Push(next);
    }
     
    /* After iterating over the
    loop, the remaining elements
    in stack do not have the next
    greater element, so -1 for them */
    while (s.Count > 0)
    {
        int element = s.Pop();
        ans[j] = -1;
        j++;
    }
 
    // return the next greatest array
    return ans;
}
 
// Driver Code    
public static void Main(string[] args)
{
    int[] arr = new int[] {3, 4, 2, 7, 5, 8, 10, 6};
    int[] query = new int[] {3, 6, 1};
    int[] ans = GFG.query(arr, query);
 
    // getting output array
    // with next greatest elements
    for (int i = 0; i < query.Length; i++)
    {
        // displaying the next greater
        // element for given set of queries
        Console.Write(ans[query[i]] + " ");
    }
}
}
 
// This code is contributed by Shrikant13


Javascript


输出:

8 -1 7