Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 确定A+;B=C存在于n个整数的数组中_Arrays_Algorithm_Integer_Linear Algebra - Fatal编程技术网

Arrays 确定A+;B=C存在于n个整数的数组中

Arrays 确定A+;B=C存在于n个整数的数组中,arrays,algorithm,integer,linear-algebra,Arrays,Algorithm,Integer,Linear Algebra,这是我的一个朋友的家庭作业(在算法和数据结构课程中)中遇到的一个问题。他问我这件事。然而,我无法解决这个问题,在过去的几天里,我已经思考了一段时间 在[0231-1]范围内有n个随机整数(可能有重复的。确定这些数字中的3个是否满足A+B=C) 我首先提出了一个简单的算法,就是O(n2logn)。 然后我提出了一个算法,即O(n2)。下面是伪代码: sort(a); // non-descending for (i = 0; i < n; i++) { j = i; k = i + 1;

这是我的一个朋友的家庭作业(在算法和数据结构课程中)中遇到的一个问题。他问我这件事。然而,我无法解决这个问题,在过去的几天里,我已经思考了一段时间

在[0231-1]范围内有n个随机整数(可能有重复的。确定这些数字中的3个是否满足A+B=C)

我首先提出了一个简单的算法,就是O(n2logn)。 然后我提出了一个算法,即O(n2)。下面是伪代码:

sort(a); // non-descending
for (i = 0; i < n; i++) {
  j = i; k = i + 1;
  while (j < n && k < n) {
    if (a[i] + a[j] == a[k])
      return true;
    else if (a[i] + a[k] < a[j])
      k++;
    else
      j++;
  }
}
return false;
排序(a);//非降序
对于(i=0;i

然而,问题表明,1O(n^2)算法(包括您的算法)都会运行得非常快。事实上,实际复杂性将是
O(n*logn)
(排序的复杂性)。
这很像快速排序,我们有
O(n*logn)
average和一个很小的命中
O(n^2)

10^6
随机数给我们提供了
~10^6*10^6
范围内的“几乎随机”和
~0..10^9
。其中一个
10^12
随机和等于整数范围内给定随机值的几率有多大?非常好。
现在,这些
10^12
随机和中的一个等于给定随机值10^6
中的一个的概率有多大?100%,诗意地说

我已经实现了您提出的解决方案,因为
n=10^6
它在最内部的循环中平均执行
5000-10000
操作。对于
O(n^2)
,就到此为止。排序是其中最昂贵的操作

另外,如果您将解决方案更新为使用散列而不是排序,则可以进一步降低复杂性,使其更均匀

用java编写的测试程序,供参考。运行它,自己看看

    int n = 1000000;
    int[] a = new int[n];

    // generate random array
    Random r = new Random();
    for (int i = 0; i < n; ++i) {
        do {
            a[i] = r.nextInt();
        } while (a[i] < 0);
    }

    Arrays.sort(a);

    // number of operations inside main loop
    int ops = 0;

    // main logic, pretty much as OP described it
    boolean found = false;
    for (int i = 0; i < n && !found; ++i) {
        int j = i;
        int k = i + 1;
        while (k < n) {
            ++ops;

            if (a[i] > a[k] - a[j]) {
                ++k;
            } else if (a[i] < a[k] - a[j]) {
                ++j;
            } else {
                System.out.println(a[i] + " + " + a[j] + " = " + a[k]);
                found = true;
                break;
            }
        }
    }

    System.out.println(ops);
int n=1000000;
int[]a=新的int[n];
//生成随机数组
随机r=新随机();
对于(int i=0;ia[k]-a[j]){
++k;
}else如果(a[i]
在Python中使用哈希的算法需要10-900微秒(平均:200中位数:60):

它是
O(N**2)
但它似乎足够快

相比之下,创建
冻结集的摊销
O(N)
操作需要
270
毫秒(比搜索慢1000倍),创建随机列表需要
0.9

注意:
random.sample
如果输入序列包含唯一元素,则不会返回重复的元素,因此
frozenset
不会丢弃上述示例中的任何元素。要解决允许重复元素的随机序列的问题,我们应使用两种数据结构:

#!/usr/bin/env python
import random

L = [random.randrange(2**31) for _ in xrange(10**6)]
S = frozenset(L)
print len(L), len(S)
print next(((a, b, a+b) for a in L for b in L if (a + b) in S), None)
输出 一般的问题是,是否有比二次算法更好的算法是公开的

因此,如果您需要更快的算法,您可能需要利用它们是32位的事实。

a+B=C,因此 B=C-A或A=C-B

通过使用哈希表,可以在O(n)复杂度下解决上述问题

var C; // the sum you are looking for
for(each element)
    X = C - element
    boolean exists = lookup for X in hash table
    if (exists) combination A+B=C exists in the given input
    else hashtable.put(element)
希望这能有所帮助。

在对排序列表进行测量时,我得到了O(n log n):

from bisect import bisect_right
import cProfile as prof
import random

def find3sum(T):
    if len(T) < 3:
        return None
    n = len(T)
    top = T[-1]
    for i in range(len(T)-1):
        b = top - T[i]
        if b < T[i]:
            return None
        k = bisect_right(T, b, i, n-1)
        while k > i:
            c = T[i] + T[k]
            j = bisect_right(T, c, k, n-1)
            if j <= k:
                break
            elif T[j] == c:
               return (i, k, j)
            else:
               k -= 1

def test_one(a):
    a = sorted(a)
    r = find3sum(a)
    i, k , j = r
    assert a[i] + a[k] == a[j]

def test():
    n = 100000
    max = 200000
    random.seed(0)
    for _ in range(100):
        a = [random.randint(0,max) for _x in xrange(n)]
        test_one(a)
        a = range(n)
        test_one(a)

prof.run('test()')
从对分导入对分\u右
导入cProfile作为prof
随机输入
def find3sum(T):
如果len(T)<3:
一无所获
n=长度(T)
top=T[-1]
对于范围内的i(透镜(T)-1):
b=顶部-T[i]
如果bi时:
c=T[i]+T[k]
j=对分_右(T,c,k,n-1)

如果j,你有证据表明有一个更快的解决方案O(n^2)?数字排序了吗?如果(a[i]+a[k]var C; // the sum you are looking for for(each element) X = C - element boolean exists = lookup for X in hash table if (exists) combination A+B=C exists in the given input else hashtable.put(element)
from bisect import bisect_right
import cProfile as prof
import random

def find3sum(T):
    if len(T) < 3:
        return None
    n = len(T)
    top = T[-1]
    for i in range(len(T)-1):
        b = top - T[i]
        if b < T[i]:
            return None
        k = bisect_right(T, b, i, n-1)
        while k > i:
            c = T[i] + T[k]
            j = bisect_right(T, c, k, n-1)
            if j <= k:
                break
            elif T[j] == c:
               return (i, k, j)
            else:
               k -= 1

def test_one(a):
    a = sorted(a)
    r = find3sum(a)
    i, k , j = r
    assert a[i] + a[k] == a[j]

def test():
    n = 100000
    max = 200000
    random.seed(0)
    for _ in range(100):
        a = [random.randint(0,max) for _x in xrange(n)]
        test_one(a)
        a = range(n)
        test_one(a)

prof.run('test()')
   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.002    0.002  183.764  183.764 <string>:1(<module>)
      200    0.005    0.000   89.996    0.450 find2sum.py:25(test_one)
        1   17.269   17.269  183.762  183.762 find2sum.py:31(test)
      200   35.096    0.175   79.601    0.398 find2sum.py:5(find3sum)
 10000000   44.958    0.000   52.398    0.000 random.py:160(randrange)
 10000000   23.891    0.000   76.289    0.000 random.py:224(randint)
        1    0.000    0.000    0.000    0.000 random.py:99(seed)
 19599982   44.077    0.000   44.077    0.000 {_bisect.bisect_right}
        1    0.000    0.000    0.000    0.000 {function seed at 0x9a1972c}
      600    0.001    0.000    0.001    0.000 {len}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
 10000000    7.440    0.000    7.440    0.000 {method 'random' of '_random.Random' objects}
      301    0.635    0.002    0.635    0.002 {range}
      200   10.390    0.052   10.390    0.052 {sorted}