[英]find the value pair in 2 sorted arrays (1 value from each array) where the sum is closest to a target value
原始問題有一個2個整數的未排序列表。 為了簡化這個問題,我們只考慮輸入是2個排序的整數數組和一個整數目標。 如果有超過1個解決方案對,則值對可以重復。
例如:[7,8,14],[5,10,14]目標:20解決方案是[14,15],第一個數組為14,第二個數組之和為5,最接近20。
我的解決方案是從頭到尾遍歷兩個數組,並與跟蹤的最小差異進行比較,並在新差異較小時進行更新。
但這是蠻力。 有沒有更好的解決方案?
我在網上找到的大多數解決方案是從同一個陣列中找到目標,2個陣列目標問題和1個陣列之間是否有任何相似之處?
一個關鍵的洞察力:給定一對(x,y),其總和高於目標,該總和比任何對(x,y')的總和更接近,其中y'> y。 相反,如果(x,y)的和低於目標,則該和比任何對(x',y)的總和更接近,其中x'<x。
這產生了線性時間的算法:
在Java中:
private static Pair<Integer, Integer> findClosestSum(List<Integer> X, List<Integer> Y, int target) {
double bestDifference = Integer.MAX_VALUE;
Pair<Integer, Integer> bestPair = null;
int xIndex = 0;
int yIndex = Y.size() - 1;
while (true) {
double sum = X.get(xIndex) + Y.get(yIndex);
double difference = Math.abs(sum - target);
if (difference < bestDifference) {
bestPair = new Pair<>(X.get(xIndex), Y.get(yIndex));
bestDifference = difference;
}
if (sum > target) {
yIndex -= 1;
if (yIndex < 0) {
return bestPair;
}
} else if (sum < target) {
xIndex += 1;
if (xIndex == X.size()) {
return bestPair;
}
} else {
// Perfect match :)
return bestPair;
}
}
}
您可以通過起始段落中的邏輯證明此算法是詳盡無遺的。 對於沒有被訪問的任何一對,必須有包括被訪問,它的兩個元件中的一個的一對,並具有嚴格更接近目標的總和。
編輯:如果您只想要小於目標的總和(不是那些超調的那些),則仍然適用相同的邏輯。 在過沖情況下,(x,y')與(x,y)一樣無效,因此它不能是更好的候選和。 在這種情況下,只需要修改第2步,只有當它是迄今為止最接近的非超越總和時才存儲總和。
謝謝你的算法,我實現了我的邏輯。 是的,它確實需要是目標下面最接近的一對,所以我相應地進行了代碼更改。 由於輸入可能是重復的,因此我也確保了句柄。 結果也可能是多個,因此也可以處理。 如果您發現任何潛在的優化,請告訴我。 這是代碼:
public static List<List<Integer>> findClosest(int[] x, int[] y, int target){
List<List<Integer>> result = new ArrayList<List<Integer>>();
int[] pair = new int[2];
int bestDiff = Integer.MIN_VALUE;
int xIndex = 0;
int yIndex = y.length - 1;
//while left doesn't reach left end and right doesn't reach right end
while(xIndex < x.length && yIndex >= 0){
int xValue = x[xIndex];
int yValue = y[yIndex];
int diff = xValue + yValue - target;
//values greater than target, y pointer go right
if(diff > 0){
yIndex--;
while(yIndex > 0 && yValue == y[yIndex - 1]) yIndex--;
}else{//combined == 0 which match target and < 0 which means the sum is less than target
//duplicates result, just add
if(diff == bestDiff){
result.add(Arrays.asList(xValue, yValue));
}
//found better pair, clear array and add new pair
else if(diff > bestDiff){
result.clear();
result.add(Arrays.asList(xValue, yValue));
bestDiff = diff;
}
xIndex++;
}
}
return result;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.