// Checks whether the array contains two elements whose sum is s.
// Input: A list of numbers and an integer s
// Output: return True if the answer is yes, else return False
public static boolean calvalue (int[] numbers, int s){
for (int i=0; i< numbers.length; i++){
for (int j=i+1; j<numbers.length;j++){
if (numbers[i] < s){
if (numbers[i]+numbers[j] == s){
return true;
}
}
}
}
return false;
}
回答
您可以通过排序数组解决这个问题,然后继续2个指针开始和数组的结尾,并通过移动两个指针找到2号。排序步骤采用O(nlog n),第二步采用O(n)。
由于@Adam指出,这也很好地从数组中删除重复的元素,让你可以从第二个步骤的时间缩短,如果数组包含许多重复的号码。
至于如何做第二步:
- 将指针在结束后向如果当前2数之和大于n。
- 如果当前2个数字的和小于n,则将指针移动到开始位置。
- 当两个指针指向相同的元素时停止和拒绝。如果总和等于n,则接受。
为什么这是正确的(我用的右端表示较大端和左端表示小端):
- 如果总和大于n,则使用权到底有没有点因为所有大于当前左端的数字都会使情况变得更糟。
- 如果sum小于n,则使用左端没有意义,因为小于当前右端的所有数字都会使其变差。
- 在每一步,我们都会经历所有可能的组合(逻辑上)在被移除的数字和剩下的数字之间。最后,我们将耗尽所有数字对之间所有可能的组合。
很好的答案。我还会增强分拣机来覆盖重复的条目 - 该列表只需要一个集合。这会略微提高步骤2的性能,因为您不会重复测试相同的数字。 然而,这会破坏你的名单。您可以保留一个查找表,在排序过程中统计列表中遇到的数字副本的数量(如果您使用分治/排序排序,则不起作用) - 那么您知道在第2步中要跳过多少个元素。这不会达到一个数量级的改善,但它可能是重要的取决于你的数据集。 – Adam
这可以在O(N)来实现。
- 从列表中创建一个哈希备份集,使其包含列表的所有元素。这需要O(n)。
- 通过列表中的每个元素
n
,计算s-n = d
,并检查集合中是否存在d
。如果d
存在,那么n+d = s
,所以返回true
。如果您在没有找到合适的d
的情况下通过列表,请返回false
。这是通过你的列表一次完成的,每次查找都需要O(1),所以这一步也需要O(n)。
无论是在其他的答案中提到这个主题的解决方案,以及一些其他的答案,以及(例如,使用位图,而不是一个哈希表),出现在以下的重复和问题的细微变化:
•Find two elements in an array that sum to k,
•Find a pair of elements from an array whose sum equals a given number,
•Determine whether or not there exist two elements in set s whose sum is exactly,
•Checking if 2 numbers of array add up to i,
•Find pair of numbers in array that add to given sum,
•Design an algorithm to find all pairs of integers within an array which sum to a,
•Given an unsorted array find any two elements in the array whose sum is equal t,
•A recursive algorithm to find two integers in an array that sums to a given inte,
•Find 2 numbers in an unsorted array equal to a given sum,
•Find two elements so sum is equal to given value,
•和,每个谷歌,many more。
这里是一个解决方案女巫考虑到重复条目。它是用javascript编写的,并假定数组已排序。
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;
}
享受!
在Java
private static boolean find(int[] nums, long k, int[] ids) {
// walk from both sides towards center.
// index[0] keep left side index, index[1] keep right side index,
// runtime O(N)
int l = ids[0];
int r = ids[1];
if (l == r) {
ids[0] = -1;
ids[1] = -1;
return false;
}
if (nums[l] + nums[r] == k) {
ids[0]++;
ids[1]++;
return true;
}
if (nums[l] + nums[r] < k) {
ids[0]++;
} else {
ids[1]--;
}
return find(nums, k, ids);
}
public static boolean twoSum(final int[] nums, int target) {
// Arrays.sort(nums); //if the nums is not sorted, then sorted it firstly, thus the running time will be O(NlogN)
int[] ids = new int[2];
ids[0] = 0;
ids[1] = nums.length - 1;
return find(nums, target, ids);
}
测试
@Test(timeout = 10L, expected = Test.None.class)
public void test() {
Assert.assertEquals(twoSum(new int[]{3, 2, 4}, 6), true);
Assert.assertEquals(twoSum(new int[]{3, 2, 4}, 8), false);
}
IF唯一的答案是不够的,想知道哪一个是i和j的A [1] + A [J] =目标
用@cheeken的想法如下,如果有重复的号码,先拿出那个。
public static int[] twoSum2(final int[] nums, int target) {
int[] r = new int[2];
r[0] = -1;
r[1] = -1;
Set<Integer> set = new HashSet<>(nums.length);
Map<Integer, List<Integer>> map = new HashMap<>(nums.length);
for (int i = 0; i < nums.length; i++) {
int v = nums[i];
if (set.contains(target - v)) {
r[0] = map.get(target - v).get(0);
r[1] = i;
return r;
}
set.add(v);
List ids = map.get(v);
if (ids == null) {
ids = new LinkedList<>();
ids.add(i);
map.put(v, ids);
} else {
ids.add(i);
map.put(v, ids);
}
}
return r;
}
测试
int[] r = twoSum2(new int[]{3, 2, 4}, 6);
Assert.assertEquals(r[0], 1);
Assert.assertEquals(r[1], 2);
r = twoSum2(new int[]{3, 2, 4}, 8);
Assert.assertEquals(r[0], r[1]);
Assert.assertEquals(r[1], -1);
- 1. Java:如何确定一个数组是否有两个相等的元素?
- 2. 如何使用递归算法来确定数组是否包含两个总和给定整数的元素?
- 3. 确定数组元素是否包含图像
- 4. 确定一个数组是否包含一个偶数
- 5. 确定一个列表是否包含独特元素
- 6. 数组是否有一个元素等于元素?
- 7. 确定一个数组是否经常包含另一个数组的所有元素?
- 8. 确定两个复数是否相等
- 9. 如何确定任何给定的连续数组元素的和是否等于ruby中给定的数字?
- 10. 确定一个数字是否包含特定的素数因子
- 11. LINQ:确定两个序列是否包含完全相同的元素
- 12. WSO2:确定消息是否包含特定元素
- 13. 确定li元素是否包含特定文本
- 14. 如何有效地确定IEnumerable是否包含多个元素?
- 15. 如何确定一个数组是否包含在另一个数组中
- 16. 确定一个数组是否在另一个数组中包含
- 17. 包含相同元素的两个数组不能相等吗?
- 18. 检查一个元素是否包含在两个不同的数组中
- 19. 是否可以定义包含属性组的元素组?
- 20. VueJS2:如何检查数组是否包含特定元素?
- 21. 一个元素是否包含指定的字符串(纯JS)?
- 22. python:如何确定一个字符串是否包含一个元组?
- 23. 确定是否所有元素的数组是素数
- 24. 确定在java中两个数组的部分是否相等
- 25. 递归:确定数组A中是否有两个元素总和为k
- 26. 确定两个集合是否共享至少一个元素
- 27. 确定dom元素是否包含突出显示的文本
- 28. 如何确定2D数组是否包含特定数字?
- 29. 如何确定一个单元格是否包含按钮
- 30. 如何测试数组是否至少包含一个元素
排序,然后从两端蔓延。 – nhahtdh
作业?你的代码中有一个错误。 如果您的输入为[1,0],if(numbers [i]
Adam