[英]Find maximum elements whose sum is less than k
這是我上周試過的一個 hackerrank 程序。 購物車中有一個項目列表,每個項目都有與之相關的成本。
有n
件物品, ith
件物品的成本是i
美元, m
件物品已經被購買並在數組arr
中表示。 目前,有k
美元,求用這筆錢購買任意數量的物品后,總共可以擁有的不同物品的最大數量。
例子:
Consider n=10,m=3,k=10,arr=[1,3, 8].
因此,任務是找出除 {1,3,8} 項外,10 美元內可以購買 10 項不同項的最大數量。 除了給定的 3 件商品外,最多可以購買 2 件商品,假設商品 - 2 和商品 - 5。總成本=2+5=7,小於 10。
讓我們考慮三個項目 - Item - 2, Item - 4, 200,
答案是 5 (3 個已經購買,2 個剛剛購買)。
function 必須返回 integer,表示可以購買的不同項目的最大數量。
function 具有以下參數:
n : an integer denoting the number of items arr[m]: an integer array denoting already purchased items
k : an integer denoting amount in dollars Constraints
約束 -
1≤n≤10^6
1≤m≤10^5
1≤k≤10^9
1≤a[i]≤10^6
這個問題已經由某人發布在這里,以防萬一有人想查看確切的問題。
現在,我的思考過程。 因為我有 K 美元,所以我必須找到要收集的最大元素,其總和為 k。 我從 1 到 n 開始一個數字,並檢查輸入列表中是否缺少該數字,如果是,則添加到總和,並執行此過程直到總和小於或等於k
。
public int process(int n, int k, List<Integer> arr) {
Set<Integer> set = new HashSet<>(arr);
long sum = 0;
int result = arr.size();
for(int i=1; i<=n; i++) {
if(set.contains(i) == false) {
if(sum + i <= k) {
sum += i;
result++;
}
}
}
return result;
}
現在,該程序適用於給定的示例測試用例。
其他一些測試用例是:
n=5, k=8, arr=[3,6] . Expected answer = 5
n=8, k=5, arr=[1,2] . Expected answer = 3
n=1, k=10, arr=[1] . Expected answer = 1
我的程序使用這些示例測試用例。 但是 hackerrank 還有 11 個其他隱藏的測試用例,它們都是隱藏的,但都失敗了,結果是錯誤的,我沒有看到任何 memory 錯誤或這些隱藏測試用例的超時錯誤。
現在我的問題是,解決這個問題的正確方法是什么? 正如問題所說,要找到要收集的最大元素,我從 1 到 n 開始尋找丟失的元素,這是有效的方法,但仍然失敗。
當您詢問正確的方法時,我不會發布完整的代碼,但會為您提供一些指導。 如果這不是一個好的答案,請隨時告訴我,我會刪除它。
1
到n
。 通常他們 go 從0
到n-1
,也許某處off-by-one
錯誤? 使用邊緣案例進行測試[1..n]
。 是否存在可以提前停止的條件?我在您的代碼中沒有看到任何明顯的錯誤。 對於失敗的案例(我推斷有大量數據輸入),您是否可能犯了輸入錯誤? 就溢出的可能性而言,一個int
可以容納的最大值是2,147,483,647。 從問題描述來看,一個int
應該足夠了,你不需要任何long
變量。
無論如何,我會建議一些改變:
process
內 for 循環中的退出條件,以在 for 循環中測試更大的i
值無果時中斷。 這也導致了一個簡化的循環體。process
,以便調用者只需傳遞一個Intger
數組; 從此數組創建List<Integer>
變量將由process
完成。 為什么調用者應該從問題描述中知道需要創建一個List
,它指定只傳遞一個數組?import java.util.*;
public class Test {
public int process(int n, int k, Integer[] arr) {
Set<Integer> set = new HashSet<Integer>(new ArrayList<Integer>(Arrays.asList(arr)));
int sum = 0;
int result = arr.length;
// Never let i exceed n and once you have an i value
// where the current sum + i exceeds k, you can stop:
for (int i = 1; i <= n && sum + i <= k; i++) {
if (!set.contains(i)) {
sum += i;
result++;
}
}
return result;
}
public static void main(String[] args) {
Test t = new Test();
Integer[] arr = {1, 3, 8};
System.out.println(t.process(10, 10, arr));
}
}
印刷:
5
關鍵可能是短語“找到不同項目的最大數量”中的單詞distinct嗎? 如果數組包含重復項怎么辦? 嘗試初始化結果
int result = set.size();
相反,看看它是否解決了問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.