数组元素判断和问题

给定一个数组,给定一个数sum,问这个数组中是否存在两个数a和b,使得a+b=sum。

1.数组排序 O(NlgN)

2.用两个指针first和last分别指向数组的首尾。如果data[first]+data[last]<sum,把first指针往右移动,如果data[first]+data[last]>sum,把last指针往左移动。直到找到data[first]+data[last]=sum,或者两指针相遇。O(N)

最终,O(NlgN)


给定一个数组,给定一个数sum,问这个数组中是否存在三个数a,b和c,使得a+b+c=sum。

1.数组排序 O(NlgN)

2.枚举sum-c,问题转化了和之前一样的问题。O(N*N)

最终,O(N*N)

在leetcode上有道基本一致的题目,只是在那里指定了sum=0。以下是我写的代码,好处是不需要任何额外空间。同时按照题目的要求,增加了去除重复结果的部分。

#include<algorithm>

class Solution {
public:
    vector<vector<int> > threeSum(vector<int> &num) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        
        vector<vector<int> > res;
        if(num.size()<3) return res;
        
        sort(num.begin(),num.end());
        int size = num.size();
        for(int indexA=0;indexA<size-2;indexA++){
            // remove duplicate
            if(indexA!=0&&num[indexA]==num[indexA-1]) continue;
            
            int indexB=indexA+1,indexC=size-1;           
            while(indexB<indexC){
                if(num[indexA]+num[indexB]+num[indexC]==0){
                    // remove duplicate
                    if((indexA!=indexB-1)&&(num[indexB]==num[indexB-1])){
                        indexB++;
                        indexC--;
                        continue;
                    }
                    
                    vector<int> ans;
                    ans.push_back(num[indexA]);
                    ans.push_back(num[indexB]);
                    ans.push_back(num[indexC]);
                    res.push_back(ans);
                    indexB++;
                    indexC--;
                }
                else if(num[indexA]+num[indexB]+num[indexC]<0)
                    indexB++;
                else
                    indexC--;
            }
        }
        return res;
    }
};



给定一个数组,问这个数组中是否存在四个数a,b,c和d,使得a+b+c=d。

1.得到一个辅助数组data2,data2=[data[i]+data[j]],另一个辅助数组data3=[data[i]-data[j]]。两个数组的大小都是O(N*N)。

2.问题转化成了data2和data3中是否存在相同的数。先排序O(N*N lg(N*N)),再比较O(N*N)。

最终,O(N*N*lgN)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值