• leetcode 4Sum


    题目描述:
    给定一个包含n个整数的数组S和目标整数target,在S中找4个整数a,b,c,d,使得这a + b + c + d = target。找出所有符合这种情况的四元组。最终结果中的四元组要唯一且四元组内元素非降序。
    题目来源
    http://oj.leetcode.com/problems/4sum/
    题目分析:
    先对数组排序,然后构造键为某个和sum,值为所有符合和为sum的元素对的map结构。枚举第一和第二个元素,通过target值得到剩余两个元素的和sum1,使用map中的和为sum1的对象构造第三和四个元素。
    正确性说明,假设结果集中某个四元组为a,b,c,d,枚举a,b,通过map中键为target - a - b的值中可以找到c,d,所以解一定在结果集中,剩下的是去掉重复的四元组。使用另一个map对象记录计算过程中已经出现的a,b,这样保证元素对a,b不会重复计算。在对原数组排过序的情况下,如果存在多个相同的元素对,可以保证值相同的元素对在上面介绍的第一个map中的位置相邻,那么可以通过和在结果集中的最近添加的四元组比较来保证元素对c,d不重复(a,b元素对确定的情况下)。
    示例代码:
    vector<vector<int> > fourSum(vector<int> &num, int target) {
        vector<vector<int> > ans;
        sort(num.begin(),num.end());
        map<int, vector<pair<int,int> > > m;
        map<pair<int,int>, int> sign;
        int anssize = 0;
        int numsize = num.size();
    
        for(int i = 0; i < numsize; ++i) {
            for(int j = i + 1; j < numsize; ++j) {
                m[num[i] + num[j]].push_back(pair<int, int>(i,j));
            }
        }
        for(int i = 0; i < numsize; ++i) {
            for(int j = i + 1; j < numsize; ++j) {
                if(sign.find(pair<int, int>(num[i], num[j])) != sign.end())
                    continue;
                sign[pair<int, int>(num[i], num[j])] = 1;
                int x = (target - num[i] - num[j]);
                if(m.find(x) != m.end()) {
                    for(vector<pair<int,int> >::iterator it = m[x].begin(); it != m[x].end(); ++it) {
                        if(it->first <= j) {
                            continue;
                        }
                        if(anssize == 0 || ans[anssize - 1][0] != num[i] || ans[anssize - 1][1] != num[j] ||
                            ans[anssize - 1][2] != num[it->first] ) {
                            vector<int> tmp;
                            tmp.push_back(num[i]);
                            tmp.push_back(num[j]);
                            tmp.push_back(num[it->first]);
                            tmp.push_back(num[it->second]);
                            ans.push_back(tmp);
                            ++anssize;
                        }
                    }
                }
            }
        }
    
        return ans;
    }
  • 相关阅读:
    light oj 1105 规律
    light oj 1071 dp(吃金币升级版)
    light oj 1084 线性dp
    light oj 1079 01背包
    light oj 1068 数位dp
    light oj 1219 树上贪心
    light oj 1057 状压dp TSP
    light oj 1037 状压dp
    矩阵快速幂3 k*n铺方格
    矩阵快速幂2 3*n铺方格
  • 原文地址:https://www.cnblogs.com/daijinqiao/p/3348645.html
Copyright © 2020-2023  润新知