给出N
个整数数组。遍历整个数组,然后选择包含相同值的K个位置。然后将这些选定的K
从数组中删除。如果我们无法选择K
值,则无法从阵列中删除任何地方。
任务是在每次迭代后最小化数组中可用的不同整数的数量。
对于给定的Q
查询,每个查询都带有数字P
。对于每个查询,在进行P
次迭代后,打印出数组中存在的不同整数的数量。
1<= N <= 10^6
1<= K <= 10
1<= Q <= 10^5
0<= C <= 10^5
1 <= P <= N
Example:
N=5
K=1
Q=3
Array = [5,0,1,2,1];
Queries (Various P values):
1
5
3
Output:
3
0
1
当P = 3时的解释:
1. First iteration, we can remove element 1 with value `5`.
2. Second iteration, we can remove element 2 with `0`.
3. Third iteration, we can remove element 4 with value `2`.
最后一个数组仅包含两个值为1
的元素。 因此剩余的不同颜色数为1。
这是我尝试过的代码,但是在满足要求方面陷入了困境:
static int getDistinctFeatures(int[] array, int size, int K, int P) {
Map<Integer, Integer> map = new LinkedHashMap<>();
// Count the occurrence of each element in the array
for (int i : array) {
map.put(i, map.getOrDefault(i, 0) + 1);
}
Set<Integer> keys = map.keySet();
List<Integer> keyList = new ArrayList<>(keys);
int index = 0;
for (int i = 0; i < P && index < keyList.size(); i++) {
int key = keyList.get(index);
index++;
int count = map.get(key);
if (count == 1) {
map.remove(key);
} else {
// What to do here
}
}
return map.size();
}
答案 0 :(得分:1)
这是一种建议的方法。
value
到count_of_value
的地图k
整除的计数值。 count_incommensurate
是您无法摆脱的几个值。count_of_value / k
的数组。对于您而言,这些步骤将导致以下结果。初始地图为:
{
0: 1,
1: 2,
2: 1,
5: 1,
}
所有可被k=1
整除的值,因此count_incommensurate = 0
。
以递增顺序排列的计数数组为[1, 1, 1, 2]
。
现在,我们进入查找数组。它从0
开始,总数为4
。 [4, ...
这样。现在,我们将每个数字写为递减之前的计数次数,并在0处停止。因此我们得到[4, 3, 2, 1, 1]
。换句话说
counts: [1, 1, 1, 2 ]
lookup: [4, 3, 2, 1, 1]
如果我们的计数是[1, 2, 3]
,我们反而会得到
counts: [1, 2 , 3 ]
lookup: [3, 2, 2, 1, 1, 1]
但是回到我们实际得到的。 [4, 3, 2, 1, 1]
是用于查找的基于0的数组,最后所有内容都是0
'
现在进行查找。
查询1
加上不相称的内容给我们3 + 0 = 3
。
查找5
结束了,所以我们得到了0 + 0 = 0
。
查询3
给我们1 + 0 = 0
。
如果我们用k=2
重复此练习,我们会发现count_incommensurate
是3
,并且查找数组最终变成了[1]
。 (经过零次迭代后,元素1
仍然存在。)由于所有查找都已结束,因此我们将以3, 3, 3
作为答案。
此算法的时间为O(N + Q)
。鉴于需要O(N)
来扫描值,以及O(Q)
来扫描查询,因此您在此方面的改进不能超过一个恒定的因素。
答案 1 :(得分:1)
这是我根据@btilly 建议的算法编写的答案。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
class Main {
public static void main(String args[] ) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] num_arr;
num_arr = br.readLine().split("\\s");
int [] nkq_arr = new int[3];
for(int i=0;i<3;i++)
{
nkq_arr[i] = Integer.parseInt(num_arr[i]);
}
int N = nkq_arr[0];
int K = nkq_arr[1];
int Q = nkq_arr[2];
int i = 0,j = 0;
String[] param_arr;
param_arr = br.readLine().split("\\s");
int [] arr = new int[N];
while(i < N)
{
arr[i] = Integer.parseInt(param_arr[i]);
i++;
}
int[] queries = new int[Q];
while(j < Q)
{
queries[j] = Integer.parseInt(br.readLine());
j++;
}
for(int c=0;c<Q;c++)
{
System.out.println(minFeatures(arr,N,K,queries[c]));
}
}
static int minFeatures (int [] arr, int N, int K, int query)
{
HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
int count=0;
for(int i=0;i<N;i++)
{
if(!map.containsKey(arr[i]))
{
map.put(arr[i],1);
count++;
}
else
{
Integer b = map.get(arr[i]);
b+=1;
map.replace((Integer)arr[i],b);
}
}
List<Integer> relevant_arr = new ArrayList();
int improper_count=0;
int relevant_arr_length = 0;
for(Integer val : map.values())
{
if(val%K==0)
{
relevant_arr.add(val/K);
relevant_arr_length++;
}
else
{
improper_count++;
}
}
Collections.sort(relevant_arr);
List<Integer> lookUp_arr = new ArrayList();
int alpha = 0;
int overall_length=0;
while(alpha < relevant_arr_length)
{
int number_of_times = relevant_arr.get(alpha);
int beta = number_of_times;
while(beta > 0)
{
lookUp_arr.add(count);
beta--;
overall_length++;
}
count--;
alpha++;
}
if(query > overall_length-1)
{
return improper_count;
}
else
{
return improper_count + lookUp_arr.get(query);
}
}
}
答案 2 :(得分:0)
@btilly 建议的算法的 Python 实现。
from collections import defaultdict
def evaluateMin(arrQ,k,queryArr):
ans = []
countMap = defaultdict(lambda : 0)
for value in arrQ:
countMap[value] +=1
counts=[]
presentEveryTime = 0
for value in countMap:
if countMap[value] % k != 0:
presentEveryTime +=1
else:
counts.append(int(countMap[value]/k))
# Creating Lookup Array
counts = sorted(counts)
lookup = []
# print(counts)
appender = len(counts)
for count in counts:
for i in range(count):
lookup.append(appender)
if appender != 1:
appender -=1
# print(lookup,presentEveryTime)
for query in queryArr:
if query >= len(lookup):
ans.append(0+presentEveryTime)
else:
ans.append(lookup[query]+presentEveryTime)
return ans
print(evaluateMin([5,0,1,2,1,1,1],2,[1,5,3,0,2]))