我需要一个算法来确定一个数组是否包含两个与给定整数相加的元素。
数组已排序。
算法应递归并在O(n)中运行。
递归步骤应该基于总和,这意味着方法传递总和并根据最终结果返回true或false(如果找到两个元素 - 返回true,否则返回false)
只能使用线性数据结构。
任何想法都受到赞赏..
答案 0 :(得分:3)
您可以使用(例如)tail recursion将任何迭代算法转换为递归算法。如果不是家庭作业,我会更加宽容。我想你会从另一篇文章中理解它。
答案 1 :(得分:1)
通常我会使用Map,但由于其中一个要求是使用线性数据结构,我认为这是排除的,所以我会使用布尔数组。
public boolean hasSum( int[] numbers, int target )
{
boolean[] hits = new boolean[ target + 1 ];
return hasSumRecursive( 0, numbers, target, hits );
}
public boolean hasSumRecursive( int index, int[] numbers, int target, boolean[] hits )
{
...
}
希望这是一个很好的暗示。
答案 2 :(得分:1)
我认为哈希是好的,例如,1,3,7,9,12,14,33 ......
如果我们想要sum = 21,我们将数字哈希到哈希表中,那么,O(n)。
我们迭代它们,当我们得到7时,我们让21-7 = 14,所以我们哈希14,我们可以找到它。所以7 + 14 = 21,
我们得到了它!
答案 3 :(得分:1)
这是一个考虑重复条目的解决方案。它是用javascript编写的,并假设数组已排序。该解决方案在O(n)时间运行,除变量外不使用任何额外的内存。
var count_pairs = function(_arr,x) {
if(!x) x = 0;
var pairs = 0;
var i = 0;
var k = _arr.length-1;
if((k+1)<2) return pairs;
var halfX = x/2;
while(i<k) {
var curK = _arr[k];
var curI = _arr[i];
var pairsThisLoop = 0;
if(curK+curI==x) {
// if midpoint and equal find combinations
if(curK==curI) {
var comb = 1;
while(--k>=i) pairs+=(comb++);
break;
}
// count pair and k duplicates
pairsThisLoop++;
while(_arr[--k]==curK) pairsThisLoop++;
// add k side pairs to running total for every i side pair found
pairs+=pairsThisLoop;
while(_arr[++i]==curI) pairs+=pairsThisLoop;
} else {
// if we are at a mid point
if(curK==curI) break;
var distK = Math.abs(halfX-curK);
var distI = Math.abs(halfX-curI);
if(distI > distK) while(_arr[++i]==curI);
else while(_arr[--k]==curK);
}
}
return pairs;
}
我在一家大公司的采访中解决了这个问题。他们接受了但不是我。 所以这里适合所有人。
从数组的两侧开始,慢慢向内工作,确保重复计算(如果存在)。
它只计算对,但可以重新编写
享受!
答案 4 :(得分:0)
对数组进行排序。搜索每个数字的补码(总和数)。复杂性O(nlogn)。
答案 5 :(得分:0)
这是我的解决方案:我迭代直到第一个数字大于期望的总和,然后直到第二个或两个的总和大于期望的总和。如果我不想要正确的答案,我将返回{-1,-1}(假设所有数字均为正整数)
{
private static int[] sumOfTwo(int[] input, int k) {
for (int i = 0; i < input.length - 1; i++) {
int first = input[i];
for (int j = 1; j < input.length; j++) {
int second = input[j];
int sum = first + second;
if (sum == k) {
int[] result = {first, second};
return result;
}
if (second > k || sum > k) {
break;
}
}
if (first > k) {
break;
}
}
int[] begin = {-1, -1};
return begin;
}
}
答案 6 :(得分:0)
这很容易。对数组进行排序很重要。
时间复杂度为 O(n)并且没有额外空间的正确算法是:
public static boolean isContainsSum(int[] arr, int sum) {
for (int i = 0, j = arr.length - 1; i < j; ) {
if (arr[i] + arr[j] == sum)
return true;
if (arr[i] + arr[j] < sum)
i++;
else
j--;
}
return false;
}
要使其具有递归性,您只需将i
和j
迭代替换为递归调用即可:
public static boolean isContainsSumRecursive(int[] arr, int sum) {
return isContainsSumRecursive(arr, sum, 0, arr.length - 1);
}
private static boolean isContainsSumRecursive(int[] arr, int sum, int i, int j) {
if (i == j)
return false;
if (arr[i] + arr[j] == sum)
return true;
if (arr[i] + arr[j] < sum)
return isContainsSumRecursive(arr, sum, i + 1, j);
return isContainsSumRecursive(arr, sum, i, j - 1);
}
答案 7 :(得分:0)
这是执行groupSum的递归方法
public boolean groupSum(int start, int[] nums, int target)
{
if (start >= nums.length) {
return (target == 0);
}
return groupSum(start + 1, nums, target - nums[start]) || groupSum(start +
1,nums,target)
}