所以,我有一个整数列表。我需要找出是否可以通过列表中的任何两个数字添加特定数字(非唯一数字)。 到目前为止我所拥有的:
boolean cs = false;
t:
for(Integer i1 : primes) {
for(Integer i2 : primes) {
if(i1 + i2 == i) {
cs = true;
break t;
}
}
}
不幸的是,随着这个列表越来越高(因为每次没有两个总和,它必须找到并创建一个新的和来保持序列运行),这个函数需要指数地执行更长时间。有什么方法可以防止这样的问题吗?随着这个功能进入成千上万,它或多或少只会因为需要多长时间而停止。
答案 0 :(得分:0)
首先,对列表进行排序。
然后在列表中启动两个游标,两个游标在两端。在循环中,将游标下的两个值相加。如果它小于你想要的总数,则将左(较小)光标向右推进一步(“较大”方向。)如果总和较大,则将右(较小)光标向前推进一步。
如果有一对总和达到你想要的总和,就可以找到它。排序列表需要O(n log n)
时间,并且O(n)
时间来运行游标循环。总的来说,它是O(n log n)
,希望能够快速满足您的需求。
修改强>
实际上,有一个线性时间,线性空间算法来做到这一点。假设您的目标号码为k
。对于列表中的每个整数i
,将k - i
插入哈希集。然后检查集合中是否已i
。如果是,则必须是因为k - i
之前已在列表中遇到过。这可能是@SpiderPig暗示的算法。
答案 1 :(得分:0)
这是对整数列表进行排序和二进制搜索的基本实现。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
/**
<P>{@code java OrderIntListXmpl}</P>
**/
public class OrderIntListXmpl {
public static final void main(String[] igno_red) {
int[] aiNums = new int[] {1, 11, 29, 12, 13, 19, 7, 2, 6, 16, 10, 15, 112, 18, 20, 3, 8, 5, 9, 14};
System.out.println("Unsorted: " + Arrays.toString(aiNums));
ArrayList<Integer> alNums = new ArrayList<Integer>(aiNums.length);
for(int i : aiNums) {
alNums.add(i);
}
Collections.sort(alNums);
System.out.println("Sorted: " + Arrays.toString(alNums.toArray()));
int ixOf12 = Collections.<Integer>binarySearch(alNums, 12);
System.out.println("Index of number 12: " + ixOf12);
}
}
输出:
[C:\java_code\]java OrderIntListXmpl
Unsorted: [1, 11, 29, 12, 13, 19, 7, 2, 6, 16, 10, 15, 112, 18, 20, 3, 8, 5, 9, 14]
Sorted: [1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 29, 112]
Index of number 12: 10
的Javadoc
答案 2 :(得分:0)
您可以尝试从普林斯顿教授Robert Segwick修改此example。它找到两个总和为0的数字。
有两个算法,一个是你使用Brute force和O(n2)。另一个nLog(n)跟随排序并否定另一个数字example。
答案 3 :(得分:0)
为了尽可能快地使用数组。 这是一个例子。
class Primes {
static int[] primeSieve(int max) {
boolean[] sieve = new boolean[max];
for(int i = 2; i < sieve.length; i++) {
sieve[i] = true;
}
int prime = 2;
while(prime*prime < max) {
for(int i = prime*2; i < max; i += prime) {
sieve[i] = false;
}
prime++;
while(!sieve[prime]) prime++;
}
int primesSize = 0;
for(int i = 0; i < max; i++) {
if(sieve[i]) primesSize++;
}
int[] primes = new int[primesSize];
for(int i = 0, j = 0; i < max; i++) {
if(sieve[i]) primes[j++] = i;
}
return primes;
}
static boolean isSummable(int num, int[] primes) {
for(int i = 0; i < primes.length && primes[i] < num; i++) {
int j = num-primes[i];
int index = java.util.Arrays.binarySearch(primes, j);
if(index >= 0) {
return true;
}
}
return false;
}
public static void main(String[] args) {
int[] primes = primeSieve(1000000);
System.out.println(primes.length);
System.out.println(isSummable(575210, primes));
}
}