判断一个数组是否存在三个元素为某一定值

最近参加了一个公司的笔试,其中有一道题如下:给定一个array,判断是否存在3个元素的和为0?
最开始看到这题没有细想特别优化的方法,居然直接采用了暴力搜索((⊙﹏⊙)b汗!),直接用了一个三层循环求解,代码如下:

bool judge(int *arr,int n){
	for(int i = 0;i<n-2;++i){
		for(int j = i+1;j<n-1;++j){
			for(int k = j+1;k<n;++k)
				if(arr[i]+arr[j]+arr[k]==0)
					return true;
		}
	}
	return false;
}

很显然这样的方法是不推荐的,复杂度太高。

改进1:首先对原数组进行排序,再用两层for循环固定前面两个数,然后第三个数用和减去前面2个数,最后采用二分查找的方法检查是否存在。该方法的复杂度为O(n^2*log(n))。

改进2:首先对原数组进行排序,除去一个固定的数字之后剩下两个数字,然后用两个指向数组的指针,一个从前往后扫描,一个从后往前扫描,记为first和last,如果 fist + last < sum 则将fist向前移动,如果fist + last > sum,则last向后移动。该方法的复杂度为O(n^2)。代码如下:

#include <iostream>  
#include <algorithm>  
using namespace std;  

void printPairSums(int data[], int size, int sum)  
{  
    int first = 0;  
    int last = size -1;  
    int s = 0;  
    while (first < last)  
    {  
        s = data[first] + data[last];  
        if (s == sum)  
        {  
            cout << data[first] << " + " << data[last] << " = " << sum << endl;  
            first++;  
            last--;  
        }  
        else if (s < sum)  
            first++;  
        else  
            last--;  
    }  
} 

int main(int argc, char* argv[])  
{  
    int data[] = {1, 5, 9, -1, 4, 6, -2, 3, -8};  
    int size = sizeof(data) / sizeof(data[0]);  
    int i;  
    sort(data, data + size);  
    printPairSums(data, size, 8);  
	
	system("pause");
    return 0;  
}

改进3:采用回溯法。代码如下:

#include <iostream>  
#include <algorithm>  
using namespace std;  

const int S = 22;  

int sumCheck(int A[], int start, int end, int arr[], int cnt){  
    if (cnt == 2){  
        int sum = arr[0] + arr[1] + arr[2];  
        if (sum == S)   
            cout << arr[0] << "\t" << arr[1] << "\t" << arr[2] << endl;  
        return 0;  
    }  
    if (start > end || cnt > 2)     
        return -1;  
  
    int i = start;  
    arr[++cnt] = A[i];  
    sumCheck(A, start + 1, end, arr, cnt);  
    arr[cnt] = 0;  
    cnt--;
    sumCheck(A, start + 1, end, arr, cnt);  
}  
int main(int argc, char* argv[])  
{  
    int A[] = {1, 4, 45, 6, 10, 8};  
    int arr_size = sizeof(A) / sizeof(A[0]);  
    int cnt = -1;  
    int arr[3] = {0, 0, 0};  
  
    sumCheck(A,0, arr_size-1, arr, cnt);  

	system("pause");
    return 0;  
}

问题的推广可参考博客求数组中多个数相加等于某一值以及面试题:检查一个数组里是否存在m个数的和等于某个值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值