📜  查询以查询数组中的一个元素,并在每次查询后将其移到最前面

📅  最后修改于: 2021-04-17 12:32:07             🧑  作者: Mango

给定一个整数M ,该整数表示最初具有数字1到M的数组。还给出了一个查询数组。对于每个查询,请在初始数组中搜索编号并将其放在数组的前面。任务是为每个查询返回给定数组中搜索到的元素的索引。
例子:

天真的方法:天真的方法是使用哈希表搜索元素,并通过执行交换线性地进行移位。对于这种方法,时间复杂度本质上将是二次的。
以下是上述方法的简单实施:

C++
// C++ program to search the element
// in an array for every query and
// move the searched element to
// the front after every query
#include 
using namespace std;
 
// Function to find the indices
vector processQueries(int Q[], int m, int n)
{
    int a[m + 1], pos[m + 1];
 
    for (int i = 1; i <= m; i++) {
        a[i - 1] = i;
        pos[i] = i - 1;
    }
 
    vector ans;
 
    // iterate in the query array
    for (int i = 0; i < n; i++) {
        int q = Q[i];
 
        // store current element
        int p = pos[q];
 
        ans.push_back(p);
 
        for (int i = p; i > 0; i--) {
 
            // swap positions of the element
            swap(a[i], a[i - 1]);
 
            pos[a[i]] = i;
        }
 
        pos[a[0]] = 0;
    }
 
    // return the result
    return ans;
}
 
// Driver code
int main()
{
    // initialise array
    int Q[] = { 3, 1, 2, 1 };
    int n = sizeof(Q) / sizeof(Q[0]);
 
    int m = 5;
 
    vector ans;
 
    // Function call
    ans = processQueries(Q, m, n);
 
    // Print answers to queries
    for (int i = 0; i < ans.size(); i++)
        cout << ans[i] << " ";
 
    return 0;
}


Java
// Java program to search the element
// in an array for every query and
// move the searched element to
// the front after every query
import java.util.*;
 
class GFG{
  
// Function to find the indices
static Vector processQueries(int Q[], int m, int n)
{
    int []a = new int[m + 1];
    int []pos = new int[m + 1];
  
    for (int i = 1; i <= m; i++) {
        a[i - 1] = i;
        pos[i] = i - 1;
    }
  
    Vector ans = new Vector();
  
    // iterate in the query array
    for (int i = 0; i < n; i++) {
        int q = Q[i];
  
        // store current element
        int p = pos[q];
  
        ans.add(p);
  
        for (int j = p; j > 0; j--) {
  
            // swap positions of the element
            a[j] = a[j] + a[j - 1];
            a[j - 1] = a[j] - a[j - 1];
            a[j] = a[j] - a[j - 1];
  
            pos[a[j]] = j;
        }
  
        pos[a[0]] = 0;
    }
  
    // return the result
    return ans;
}
  
// Driver code
public static void main(String[] args)
{
    // initialise array
    int Q[] = { 3, 1, 2, 1 };
    int n = Q.length;
  
    int m = 5;
  
    Vector ans = new Vector();
  
    // Function call
    ans = processQueries(Q, m, n);
  
    // Print answers to queries
    for (int i = 0; i < ans.size(); i++)
        System.out.print(ans.get(i)+ " ");
  
}
}
 
// This code is contributed by sapnasingh4991


Python3
# Python3 program to search the element
# in an array for every query and
# move the searched element to
# the front after every query
 
# Function to find the indices
def processQueries(Q, m, n) :
 
    a = [0]*(m + 1); pos = [0]*(m + 1);
 
    for i in range(1, m + 1) :
        a[i - 1] = i;
        pos[i] = i - 1;
 
    ans = [];
 
    # iterate in the query array
    for i in range(n) :
        q = Q[i];
 
        # store current element
        p = pos[q];
 
        ans.append(p);
 
        for i in range(p,0,-1) :
 
            # swap positions of the element
            a[i], a[i - 1] = a[i - 1],a[i];
            pos[a[i]] = i;
 
        pos[a[0]] = 0;
 
    # return the result
    return ans;
 
# Driver code
if __name__ == "__main__" :
 
    # initialise array
    Q = [ 3, 1, 2, 1 ];
    n = len(Q);
 
    m = 5;
 
    ans = [];
 
    # Function call
    ans = processQueries(Q, m, n);
 
    # Print answers to queries
    for i in range(len(ans)) :
        print(ans[i],end=" ");
 
# This code is contributed by Yash_R


C#
// C# program to search the element
// in an array for every query and
// move the searched element to
// the front after every query
using System;
using System.Collections.Generic;
 
public class GFG{
 
// Function to find the indices
static List processQueries(int []Q, int m, int n)
{
    int []a = new int[m + 1];
    int []pos = new int[m + 1];
 
    for(int i = 1; i <= m; i++)
    {
       a[i - 1] = i;
       pos[i] = i - 1;
    }
     
    List ans = new List();
 
    // Iterate in the query array
    for(int i = 0; i < n; i++)
    {
       int q = Q[i];
 
       // Store current element
       int p = pos[q];
       ans.Add(p);
 
       for(int j = p; j > 0; j--)
       {
             
          // Swap positions of the element
          a[j] = a[j] + a[j - 1];
          a[j - 1] = a[j] - a[j - 1];
          a[j] = a[j] - a[j - 1];
 
          pos[a[j]] = j;
       }
       pos[a[0]] = 0;
    }
 
    // Return the result
    return ans;
}
 
// Driver code
public static void Main(String[] args)
{
    // Initialise array
    int []Q = { 3, 1, 2, 1 };
    int n = Q.Length;
    int m = 5;
 
    List ans = new List();
 
    // Function call
    ans = processQueries(Q, m, n);
 
    // Print answers to queries
    for(int i = 0; i < ans.Count; i++)
       Console.Write(ans[i] + " ");
 
}
}
// This code is contributed by sapnasingh4991


C++
// C++ program to search the element
// in an array for every query and
// move the searched element to
// the front after every query
#include 
using namespace std;
 
// Function to update the fenwick tree
void update(vector& tree, int i, int val)
{
    // update the next element
    while (i < tree.size()) {
        tree[i] += val;
 
        // move to the next
        i += (i & (-i));
    }
}
 
// Function to  get the
// sum from the fenwick tree
int getSum(vector& tree, int i)
{
    int s = 0;
 
    // keep adding till we have not
    // reached the root of the tree
    while (i > 0) {
        s += tree[i];
 
        // move to the parent
        i -= (i & (-i));
    }
    return s;
}
 
// function to process the queries
vector processQueries(vector& queries, int m)
{
    vector res, tree((2 * m) + 1, 0);
 
    // Hash-table
    unordered_map hmap;
 
    // Iterate and increase the frequency
    // count in the fenwick tree
    for (int i = 1; i <= m; ++i) {
        hmap[i] = i + m;
        update(tree, i + m, 1);
    }
    // Traverse for all queries
    for (int querie : queries) {
 
        // Get the sum from the fenwick tree
        res.push_back(getSum(tree, hmap[querie]) - 1);
 
        // remove it from the fenwick tree
        update(tree, hmap[querie], -1);
 
        // Add it back at the first index
        update(tree, m, 1);
 
        hmap[querie] = m;
 
        m--;
    }
 
    // return the final result
    return res;
}
 
// Driver code
int main()
{
    // initialise the Queries
    vector Queries = { 4, 1, 2, 2 };
 
    // initialise M
    int m = 4;
 
    vector ans;
 
    ans = processQueries(Queries, m);
 
    for (int i = 0; i < ans.size(); i++)
        cout << ans[i] << " ";
 
    return 0;
}


Java
// Java program to search the element
// in an array for every query and
// move the searched element to
// the front after every query
import java.util.*;
class GFG{
 
// Function to update the fenwick tree
static void update(int []tree, int i, int val)
{
    // update the next element
    while (i < tree.length)
    {
        tree[i] += val;
 
        // move to the next
        i += (i & (-i));
    }
}
 
// Function to  get the
// sum from the fenwick tree
static int getSum(int []tree, int i)
{
    int s = 0;
 
    // keep adding till we have not
    // reached the root of the tree
    while (i > 0)
    {
        s += tree[i];
 
        // move to the parent
        i -= (i & (-i));
    }
    return s;
}
 
// function to process the queries
static Vector processQueries(int []queries,
                                      int m)
{
    Vectorres = new Vector<>();
    int []tree = new int[(2 * m) + 1];
 
    // Hash-table
    HashMap hmap  = new HashMap<>();
 
    // Iterate and increase the frequency
    // count in the fenwick tree
    for (int i = 1; i <= m; ++i)
    {
        hmap.put(i, i+m);
        update(tree, i + m, 1);
    }
   
    // Traverse for all queries
    for (int querie : queries)
    {
 
        // Get the sum from the fenwick tree
        res.add(getSum(tree, hmap.get(querie) - 1));
 
        // remove it from the fenwick tree
        update(tree, hmap.get(querie), -1);
 
        // Add it back at the first index
        update(tree, m, 1);
 
        hmap.put(querie, m);
 
        m--;
    }
 
    // return the final result
    return res;
}
 
// Driver code
public static void main(String[] args)
{
    // initialise the Queries
    int []Queries = { 4, 1, 2, 2 };
 
    // initialise M
    int m = 4;
 
    Vector ans;
 
    ans = processQueries(Queries, m);
 
    System.out.print(ans);
}
}
 
// This code is contributed by Rohit_ranjan


Python3
# Python3 program to search the element
# in an array for every query and
# move the searched element to
# the front after every query
 
# Function to update the fenwick tree
def update(tree, i, val):
 
    # Update the next element
    while (i < len(tree)):
        tree[i] += val
 
        # Move to the next
        i += (i & (-i))
 
# Function to get the
# sum from the fenwick tree
def getSum(tree, i):
 
    s = 0
 
    # Keep adding till we have not
    # reached the root of the tree
    while (i > 0):
        s += tree[i]
 
        # Move to the parent
        i -= (i & (-i))
    return s
 
# Function to process the queries
def processQueries(queries, m):
 
    res = []
    tree = [0] * (2 * m + 1)
 
    # Hash-table
    hmap = {}
 
    # Iterate and increase the frequency
    # count in the fenwick tree
    for i in range(1, m + 1):
        hmap[i] = i + m
        update(tree, i + m, 1)
     
    # Traverse for all queries
    for querie in queries:
 
        # Get the sum from the fenwick tree
        res.append(getSum(tree, hmap[querie]) - 1)
 
        # Remove it from the fenwick tree
        update(tree, hmap[querie], -1)
 
        # Add it back at the first index
        update(tree, m, 1)
 
        hmap[querie] = m
        m -= 1
 
    # Return the final result
    return res
 
# Driver code
if __name__ == "__main__":
     
    # Initialise the Queries
    Queries = [ 4, 1, 2, 2 ]
 
    # Initialise M
    m = 4
 
    ans = processQueries(Queries, m)
 
    for i in range(len(ans)):
        print(ans[i], end = " ")
 
# This code is contributed by chitranayal


C#
// C# program to search the element
// in an array for every query and
// move the searched element to
// the front after every query
using System;
using System.Collections.Generic;
class GFG{
 
// Function to update the fenwick tree
static void update(int []tree,
                   int i, int val)
{
    // update the next element
    while (i < tree.Length)
    {
        tree[i] += val;
 
        // move to the next
        i += (i & (-i));
    }
}
 
// Function to  get the
// sum from the fenwick tree
static int getSum(int []tree, int i)
{
    int s = 0;
 
    // keep adding till we have not
    // reached the root of the tree
    while (i > 0)
    {
        s += tree[i];
 
        // move to the parent
        i -= (i & (-i));
    }
    return s;
}
 
// function to process the queries
static List processQueries(int []queries,
                                int m)
{
    Listres = new List();
    int []tree = new int[(2 * m) + 1];
 
    // Hash-table
    Dictionary hmap  = new Dictionary();
 
    // Iterate and increase the frequency
    // count in the fenwick tree
    for (int i = 1; i <= m; ++i)
    {
        hmap.Add(i, i+m);
        update(tree, i + m, 1);
    }
   
    // Traverse for all queries
    foreach (int querie in queries)
    {
        // Get the sum from the fenwick tree
        res.Add(getSum(tree, hmap[querie] - 1));
 
        // remove it from the fenwick tree
        update(tree, hmap[querie], -1);
 
        // Add it back at the first index
        update(tree, m, 1);
        if(hmap.ContainsKey(querie))
            hmap[querie] = m;
        else
            hmap.Add(querie, m);
 
        m--;
    }
 
    // return the readonly result
    return res;
}
 
// Driver code
public static void Main(String[] args)
{
    // initialise the Queries
    int []Queries = {4, 1, 2, 2};
 
    // initialise M
    int m = 4;
 
    List ans;
    ans = processQueries(Queries, m);
    foreach (int i in ans)
        Console.Write(i + " ");
}
}
 
// This code is contributed by shikhasingrajput


输出:
2 1 2 1






有效方法:解决上述问题的有效方法是使用Fenwick树。使用以下3个操作,可以解决问题。

  1. 前推元件
  2. 查找数字的索引
  3. 更新其余元素的索引。

使用设置的数据结构以排序的方式保留元素,然后遵循以下要点:

  • 而不是将元素推到最前面,即为每个查询分配索引0。
  • 我们为第一个查询分配-1,为第二个查询分配-2,为第三个查询分配-3,依此类推,直到-m。
  • 这样做,索引的更新范围为[-m,m]
  • 对所有值[-m,m]右移m值,因此我们的新范围是[0,2m]
  • 初始化大小为2m的Fenwick树,并设置[1…m]中的所有值,即[m..2m]
  • 对于每个查询,通过查找小于给定查询的set元素数来找到其位置,完成后将其在Fenwick树中的位置设置为0。

下面是上述方法的实现:

C++

// C++ program to search the element
// in an array for every query and
// move the searched element to
// the front after every query
#include 
using namespace std;
 
// Function to update the fenwick tree
void update(vector& tree, int i, int val)
{
    // update the next element
    while (i < tree.size()) {
        tree[i] += val;
 
        // move to the next
        i += (i & (-i));
    }
}
 
// Function to  get the
// sum from the fenwick tree
int getSum(vector& tree, int i)
{
    int s = 0;
 
    // keep adding till we have not
    // reached the root of the tree
    while (i > 0) {
        s += tree[i];
 
        // move to the parent
        i -= (i & (-i));
    }
    return s;
}
 
// function to process the queries
vector processQueries(vector& queries, int m)
{
    vector res, tree((2 * m) + 1, 0);
 
    // Hash-table
    unordered_map hmap;
 
    // Iterate and increase the frequency
    // count in the fenwick tree
    for (int i = 1; i <= m; ++i) {
        hmap[i] = i + m;
        update(tree, i + m, 1);
    }
    // Traverse for all queries
    for (int querie : queries) {
 
        // Get the sum from the fenwick tree
        res.push_back(getSum(tree, hmap[querie]) - 1);
 
        // remove it from the fenwick tree
        update(tree, hmap[querie], -1);
 
        // Add it back at the first index
        update(tree, m, 1);
 
        hmap[querie] = m;
 
        m--;
    }
 
    // return the final result
    return res;
}
 
// Driver code
int main()
{
    // initialise the Queries
    vector Queries = { 4, 1, 2, 2 };
 
    // initialise M
    int m = 4;
 
    vector ans;
 
    ans = processQueries(Queries, m);
 
    for (int i = 0; i < ans.size(); i++)
        cout << ans[i] << " ";
 
    return 0;
}

Java

// Java program to search the element
// in an array for every query and
// move the searched element to
// the front after every query
import java.util.*;
class GFG{
 
// Function to update the fenwick tree
static void update(int []tree, int i, int val)
{
    // update the next element
    while (i < tree.length)
    {
        tree[i] += val;
 
        // move to the next
        i += (i & (-i));
    }
}
 
// Function to  get the
// sum from the fenwick tree
static int getSum(int []tree, int i)
{
    int s = 0;
 
    // keep adding till we have not
    // reached the root of the tree
    while (i > 0)
    {
        s += tree[i];
 
        // move to the parent
        i -= (i & (-i));
    }
    return s;
}
 
// function to process the queries
static Vector processQueries(int []queries,
                                      int m)
{
    Vectorres = new Vector<>();
    int []tree = new int[(2 * m) + 1];
 
    // Hash-table
    HashMap hmap  = new HashMap<>();
 
    // Iterate and increase the frequency
    // count in the fenwick tree
    for (int i = 1; i <= m; ++i)
    {
        hmap.put(i, i+m);
        update(tree, i + m, 1);
    }
   
    // Traverse for all queries
    for (int querie : queries)
    {
 
        // Get the sum from the fenwick tree
        res.add(getSum(tree, hmap.get(querie) - 1));
 
        // remove it from the fenwick tree
        update(tree, hmap.get(querie), -1);
 
        // Add it back at the first index
        update(tree, m, 1);
 
        hmap.put(querie, m);
 
        m--;
    }
 
    // return the final result
    return res;
}
 
// Driver code
public static void main(String[] args)
{
    // initialise the Queries
    int []Queries = { 4, 1, 2, 2 };
 
    // initialise M
    int m = 4;
 
    Vector ans;
 
    ans = processQueries(Queries, m);
 
    System.out.print(ans);
}
}
 
// This code is contributed by Rohit_ranjan

Python3

# Python3 program to search the element
# in an array for every query and
# move the searched element to
# the front after every query
 
# Function to update the fenwick tree
def update(tree, i, val):
 
    # Update the next element
    while (i < len(tree)):
        tree[i] += val
 
        # Move to the next
        i += (i & (-i))
 
# Function to get the
# sum from the fenwick tree
def getSum(tree, i):
 
    s = 0
 
    # Keep adding till we have not
    # reached the root of the tree
    while (i > 0):
        s += tree[i]
 
        # Move to the parent
        i -= (i & (-i))
    return s
 
# Function to process the queries
def processQueries(queries, m):
 
    res = []
    tree = [0] * (2 * m + 1)
 
    # Hash-table
    hmap = {}
 
    # Iterate and increase the frequency
    # count in the fenwick tree
    for i in range(1, m + 1):
        hmap[i] = i + m
        update(tree, i + m, 1)
     
    # Traverse for all queries
    for querie in queries:
 
        # Get the sum from the fenwick tree
        res.append(getSum(tree, hmap[querie]) - 1)
 
        # Remove it from the fenwick tree
        update(tree, hmap[querie], -1)
 
        # Add it back at the first index
        update(tree, m, 1)
 
        hmap[querie] = m
        m -= 1
 
    # Return the final result
    return res
 
# Driver code
if __name__ == "__main__":
     
    # Initialise the Queries
    Queries = [ 4, 1, 2, 2 ]
 
    # Initialise M
    m = 4
 
    ans = processQueries(Queries, m)
 
    for i in range(len(ans)):
        print(ans[i], end = " ")
 
# This code is contributed by chitranayal

C#

// C# program to search the element
// in an array for every query and
// move the searched element to
// the front after every query
using System;
using System.Collections.Generic;
class GFG{
 
// Function to update the fenwick tree
static void update(int []tree,
                   int i, int val)
{
    // update the next element
    while (i < tree.Length)
    {
        tree[i] += val;
 
        // move to the next
        i += (i & (-i));
    }
}
 
// Function to  get the
// sum from the fenwick tree
static int getSum(int []tree, int i)
{
    int s = 0;
 
    // keep adding till we have not
    // reached the root of the tree
    while (i > 0)
    {
        s += tree[i];
 
        // move to the parent
        i -= (i & (-i));
    }
    return s;
}
 
// function to process the queries
static List processQueries(int []queries,
                                int m)
{
    Listres = new List();
    int []tree = new int[(2 * m) + 1];
 
    // Hash-table
    Dictionary hmap  = new Dictionary();
 
    // Iterate and increase the frequency
    // count in the fenwick tree
    for (int i = 1; i <= m; ++i)
    {
        hmap.Add(i, i+m);
        update(tree, i + m, 1);
    }
   
    // Traverse for all queries
    foreach (int querie in queries)
    {
        // Get the sum from the fenwick tree
        res.Add(getSum(tree, hmap[querie] - 1));
 
        // remove it from the fenwick tree
        update(tree, hmap[querie], -1);
 
        // Add it back at the first index
        update(tree, m, 1);
        if(hmap.ContainsKey(querie))
            hmap[querie] = m;
        else
            hmap.Add(querie, m);
 
        m--;
    }
 
    // return the readonly result
    return res;
}
 
// Driver code
public static void Main(String[] args)
{
    // initialise the Queries
    int []Queries = {4, 1, 2, 2};
 
    // initialise M
    int m = 4;
 
    List ans;
    ans = processQueries(Queries, m);
    foreach (int i in ans)
        Console.Write(i + " ");
}
}
 
// This code is contributed by shikhasingrajput
输出:
3 1 2 0






时间复杂度: O(nlogn)
空间复杂度: O(2n)