【发布时间】:2011-12-28 12:39:14
【问题描述】:
我应该创建一个O(n log(n)) 算法来检查 int[] 中两个数字的总和是否 == 给定数字。
例如。给定 [1,4,7,2,3,4] 总和将是 8 (1+7) 但不是 20
给出的答案建议使用二进制排序或合并排序,但他们只是给出了合并排序算法,而没有逻辑处理这个特殊要求。然后另一个答案是:
假设 x 是我们要检查的总和,z 是 这个数组:下面的算法解决了这个问题:
- 对 S 中的元素进行排序。
- 形成集合 S' = {z : z = x − y for some y ∈ S}。
- 对 S' 中的元素进行排序。
- 如果 S 中的任何值出现多次,则删除除一个之外的所有实例。对 S' 执行相同操作。
- 合并两个排序集 S 和 S'。
- 当且仅当相同的值出现在合并输出中的连续位置时,S 中存在两个元素的和正好为 x。
为了证明第 4 步中的主张的合理性,首先观察如果有任何值 在合并输出中出现两次,必须连续出现 职位。因此,我们可以重述步骤 5 中的条件,因为存在 S 中的两个元素的和正好是 x 当且仅当相同的值 在合并的输出中出现两次。假设某个值 w 出现 两次。然后 w 在 S 中出现一次,在 S' 中出现一次。因为 w 出现在 S',存在一些 y ∈ S 使得 w = x - y,或 x = w + y。由于 w ∈ S,元素 w 和 y 在 S 中,总和为 x。
相反,假设有值 w, y ∈ S 使得 w + y = X。然后,由于 x - y = w,值 w 出现在 S' 中。因此,w 在 S 和 S',因此它会在合并的输出中出现两次。
第 1 步和第 3 步需要 O(n log n) 步。步骤 2、4、5 和 6 需要 O(n) 步。因此总体运行时间为 O(n log n)。
但我真的不明白他们的意思。在第 2 步中,x 和 y 是什么?
但是下面是我自己创建的,不知道是不是O(n log(n))?
class FindSum {
public static void main(String[] args) {
int[] arr = {6,1,2,3,7,12,10,10};
int targetSum = 20;
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
int end = arr.length - 1;
if (FindSum.binarySearchSum(arr, targetSum, 0, end, 0, end)) {
System.out.println("Found!");
} else {
System.out.println("Not Found :(");
}
}
public static boolean binarySearchSum(int[] arr, int targetSum,
int from1, int end1,
int from2, int end2) {
// idea is to use 2 "pointers" (simulating 2 arrays) to (binary) search
// for target sum
int curr1 = from1 + (end1-from1)/2;
int curr2 = from2 + (end2-from2)/2;
System.out.print(String.format("Looking between %d to %d, %d to %d: %d, %d", from1, end1, from2, end2, curr1, curr2));
int currSum = arr[curr1] + arr[curr2];
System.out.println(". Sum = " + currSum);
if (currSum == targetSum) {
// base case
return true;
} else if (currSum > targetSum) {
// currSum more than targetSum
if (from2 != end2) {
// search in lower half of 2nd "array"
return FindSum.binarySearchSum(arr, targetSum, from1, end1, from2, curr2 - 1);
} else if (from1 != end2) {
// search in lower half of 1st "array" (resetting the start2, end2 args)
return FindSum.binarySearchSum(arr, targetSum, from1, curr1 - 1, 0, arr.length - 1);
} else {
// can't find
return false;
}
} else {
// currSum < targetSum
if (from2 != end2) {
// search in upper half of 2nd "array"
return FindSum.binarySearchSum(arr, targetSum, from1, end1, curr2 + 1, end2);
} else if (from1 != end2) {
// search in upper half of 1st "array" (resetting the start2, end2 args)
return FindSum.binarySearchSum(arr, targetSum, curr1 + 1, end1, 0, arr.length - 1);
} else {
// can't find
return false;
}
}
}
}
【问题讨论】:
-
解决简单任务的复杂方式。算法描述中的那个。
-
3.对 [集合] S' 中的元素进行排序。啊。无法对集合进行排序。
标签: java big-o binary-search