满足和为定值的两个数或多个数

来源:互联网 发布:windows loader用不了 编辑:程序博客网 时间:2024/04/29 12:45

一、和接近定值的三个数

给定一个数组,任意选三个数,求这三个数之和与给定的数最接近的组合。例如给定数组S={-1,2,1,-4},定值target=1。则结果是(-1+2+1)=2。

解答:先对数组排序,之后每次选一个数,然后再固定两端,用两端向中间靠近的方式找。时间复杂度O(n^2),空间复杂度O(1)。

int threeSumClosest(vector<int> &num, int target) {        sort(num.begin(),num.end());        int m = num[0]+num[1]+num[2];        for(int i=0; i<num.size(); i++){            // 先选中元素i,再固定端点i+1和n-1,向中间移动            int low = i+1, high = num.size()-1;            while(low < high){                int cur = num[i]+num[low]+num[high];                if(abs(cur-target) < abs(m-target)) m = cur;                if(m == target) return m;   // 如果当前和跟目标值相等,则已经找到最接近的值                if(cur < target) low++;     // 当前当前和小于目标值,则左端点右移                else high--;            }        }        return m;    }
扩展:三个数和为某个定值(去重);四个数和为某个定值(去重,在外层再加一个for循环,时间复杂度O(n^3))

二、和为定值的两个数

给定一个数组,任意选两个数,找出两个数之和等于某个定值,返回这两个数的下标(小下标在前)。

解答:用hashmap存下当前元素ai相对于target的差(target-ai)。之后再扫描一遍数组查看是否有数在hashmap之中。时间复杂度O(n),空间复杂度O(n)。

vector<int> twoSum(vector<int> &numbers, int target) {        vector<int> ret;        // hashmap        unordered_map<int,int> m;        int n = numbers.size();        // 记录元素与target的差值,value记录下标        for(int i=0; i<n; i++) m.insert(make_pair(target-numbers[i],i));        for(int i=0; i<n; i++){            // 查找hashmap里面是否存在            if(m.find(numbers[i]) != m.end() && i != m[numbers[i]]){                 ret.push_back(min(i+1,m[numbers[i]]+1));                ret.push_back(max(i+1,m[numbers[i]]+1));                break;            }        }        return ret;    }
扩展:若不要求返回下标,而是返回具体哪两个数,则可以使用先排序,然后再首尾指针的方法来做。时间复杂度O(nlogn),空间复杂度O(1)。

原创粉丝点击