Algorithm 找出数组中是否有两个和为0的数字

Algorithm 找出数组中是否有两个和为0的数字,algorithm,dynamic,Algorithm,Dynamic,假设有一个数组[1,2,9,4,-5,-4],我们需要找出是否有两个数字和为0。时间复杂度应为O(n),并且只应使用恒定的额外空间。允许修改原始数组 我在面试时问了这个问题,但没有找到解决办法。谢谢。如果我们知道数组的数字范围,我们可以创建一个哈希映射,它将消耗一个恒定的额外空间来解决O(n)时间复杂度问题 #include <iostream> #include <cmath> using namespace std; int main(){ int ar

假设有一个数组[1,2,9,4,-5,-4],我们需要找出是否有两个数字和为0。时间复杂度应为O(n),并且只应使用恒定的额外空间。允许修改原始数组


我在面试时问了这个问题,但没有找到解决办法。谢谢。

如果我们知道数组的数字范围,我们可以创建一个哈希映射,它将消耗一个恒定的额外空间来解决O(n)时间复杂度问题

#include <iostream>
#include <cmath>

using namespace std;

int main(){

    int arr[]={1, 2, 9, 4, -5, -4};
    int n = sizeof(arr)/sizeof(arr[0]);

    const int N=1000001; // the maximum non negative value for arr[i] is 1,000,000
    int hashmap [N];

    bool found=false;

    for (int i=0; i<N; i++){ //initialize the hashmap
        hashmap[i]=0;
    }

    for (int i=0; i<n; i++){
        int temp = abs( arr[i] );
        if (  hashmap[ temp ] == 0  ){ // no collision 
            if (arr[i] >= 0){
                hashmap[ temp ] = 1;   //mark the hashmap 1 for positive arr[i]
            }else{
                hashmap[ temp ] = -1;  //mark the hashmap -1 for negative arr[i]
            }
        }else{                         //collision
            if (hashmap[ temp ] == 1 && arr[i] <= 0){
                found = true;
                break;
            }else if (hashmap[ temp ] == -1 && arr[i] > 0){
                found = true;
                break;
            }
        }
    }

    if (found){
        cout << "Found" << endl;
    }else{
        cout << "Not found" << endl;
    }

    return 0;
}
#包括
#包括
使用名称空间std;
int main(){
int arr[]={1,2,9,4,-5,-4};
int n=sizeof(arr)/sizeof(arr[0]);
const int N=1000001;//arr[i]的最大非负值为1000000
int hashmap[N];
bool-found=false;

对于(inti=0;i一般性评论:
如果我们可以修改原始数组,并且数组中值的大小没有限制,那么可以在数组的每个元素中存储尽可能多的信息。 看


在这种特殊情况下,您可以做得更简单

我们只需要知道数组中是否存在一个值及其负值,可以这样完成:

a:=
数组中的最大数字。
b:=
数组中最小的负数

位:=2*max(a,-b)

m
为带
位的整数变量

//现在我们读取数组(时间**O(n)**)。
对于(i=0;n>i;i++){

如果(0可能重复读取-此问题要求额外的常量空间,而使用SET的问题我与您一样不太熟悉,但当我看到这样一个具有有趣约束的问题时,我认为必须使用一些位魔术。但我不知道从何处开始。我认为此问题缺少一些约束ts,O(n)时间和O(n)空间的复杂性很简单;O(n logn)时间和O(1)空间是可行的;但我不认为O(n)时间,O(1)空间是可行的,没有额外的限制。如果数字小于32,可以将值
i
的数字存储到
int positiveSet
int negativeSet
ith
位,然后在末尾取
positiveSet
negativeSet
之间的二进制和
,并检查其大小(非)空。(0未处理)。但这感觉非常便宜
// Now we read the array (time **O(n)**).
for(i=0; n>i; i++){
  if(0<=a[n]){ 
    if(m.testBit(2*a[n] + 1))
      return true;  // negative value was already there
    m.setBit(2*a[n]);
  }
  else{ 
    if(m.testBit(2*a[-n]))
      return true;  // positive value was already there
    m.setBit(2*(-n) + 1);
}
return false;