给定一个整数M ,它表示最初具有数字 1 到 M 的数组。还给出了一个Query数组。对于每个查询,搜索初始数组中的数字并将其放在数组的前面。任务是为每个查询返回给定数组中搜索元素的索引。
例子:
Input : Q[] = {3, 1, 2, 1}, M = 5
Output : [2, 1, 2, 1]
Explanations :
Since m = 5 the initial array is [1, 2, 3, 4, 5].
Query1: Search for 3 in the [1, 2, 3, 4, 5] and move it in the beginning. After moving, the array looks like [3, 1, 2, 4, 5]. 3 is at index 2.
Query2: Move 1 from [3, 1, 2, 4, 5] to the beginning of the array to make the array look like [1, 3, 2, 4, 5]. 1 is present at index 1.
Query3: Move 2 from [1, 3, 2, 4, 5] to the beginning of the array to make the array look like [2, 1, 3, 2, 4, 5]. 2 is present at index 2.
Query4: Move 1 from [2, 1, 3, 4, 5] to the beginning of the array to make the array look like [1, 2, 3, 4, 5]. 1 is present at index 1.
Input : Q[] = {4, 1, 2, 2}, M = 4
Output : 3, 1, 2, 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 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
Javascript
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
Javascript
2 1 2 1
高效方法:解决上述问题的一种有效方法是使用 Fenwick Tree。使用以下3个操作,可以解决问题。
- 推动元素在前面
- 查找数字的索引
- 更新其余元素的索引。
使用 set 数据结构保持元素有序,然后遵循以下几点:
- 而不是将元素推到前面,即为每个查询分配一个索引 0。
- 我们为第一个查询分配 -1,为第二个查询分配 -2,为第三个查询分配 -3,依此类推,直到 -m。
- 这样做,索引的更新范围为 [-m, m]
- 将所有值 [-m, m] 右移 m 的值,所以我们的新范围是 [0, 2m]
- 初始化一个大小为 2m 的 Fenwick 树并设置 [1…m] 中的所有值,即 [m..2m]
- 对于每个查询,通过查找小于给定查询的集合元素的数量来找到它的位置,完成后将其在 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
蟒蛇3
# 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
Javascript
3 1 2 0
时间复杂度: O(nlogn)
空间复杂度: O(2n)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live