3 回答

TA貢獻1789條經驗 獲得超10個贊
這是一個建議的方法。
value
構建從到的映射count_of_value
找出有多少值的計數不能被 整除
k
。這count_incommensurate
是你無法擺脫的價值觀。對于剩余的值,通過遞增計數創建一個數組
count_of_value / k
。現在創建一個查找,按迭代次數,有多少可刪除的值。
執行查找。
在您的情況下,這些步驟會產生以下結果。初始地圖為:
{ 0: 1, 1: 2, 2: 1, 5: 1, }
k=1
可被so整除的所有值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 = 1
。
如果我們用 重復這個練習,k=2
我們會發現count_incommensurate
is3
并且我們的查找數組最終變成[1]
. (零次迭代后,該元素1
仍然存在。)由于所有查找都結束了,我們將得到3, 3, 3
答案。
這個算法的時間是O(N + Q)
。鑒于需要O(N)
掃描值和O(Q)
掃描查詢,您只能通過一個常數因子來真正改進它。需要提及的一點是,需要對初始計數數組([1, 2, 1, 1]
在本例中)進行排序,這會增加O(N log N)
問題的時間復雜度。

TA貢獻1796條經驗 獲得超10個贊
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);
}
}
}

TA貢獻2036條經驗 獲得超8個贊
建議的算法的 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]))
添加回答
舉報