代码随想录Day7-454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

75 阅读2分钟

Day7-454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

期末周复习ing,做不太出来的就直接看答案or留着以后再处理

努力坚持

454.四数相加II

n方复杂度超时

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        int n = nums1.size();
        vector<int> a;
        vector<int> b;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                a.push_back(nums1[i] + nums2[j]);
                b.push_back(nums3[i] + nums4[j]);
            }
        }
        int count = 0;
        for(int i = 0; i < n * n; i++){
            for(int j = 0; j < n * n; j++){
                if(a[i] + b[j] == 0) count ++;
            }
        }
        return count;
    }
};

标答

class Solution {
public:
    int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
        unordered_map<int, int> umap; //key:a+b的数值,value:a+b数值出现的次数
        // 遍历大A和大B数组,统计两个数组元素之和,和出现的次数,放到map中
        for (int a : A) {
            for (int b : B) {
                umap[a + b]++;
            }
        }
        int count = 0; // 统计a+b+c+d = 0 出现的次数
        // 在遍历大C和大D数组,找到如果 0-(c+d) 在map中出现过的话,就把map中key对应的value也就是出现次数统计出来。
        for (int c : C) {
            for (int d : D) {
                if (umap.find(0 - (c + d)) != umap.end()) {
                    count += umap[0 - (c + d)];
                }
            }
        }
        return count;
    }
};

383. 赎金信

和之前的字母异位词一样

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        int myMap[26] = {0};
        for(int i = 0; i < ransomNote.length(); i++){
            myMap[ransomNote[i] - 'a'] ++;
        }
        for(int i = 0; i < magazine.length(); i++){
            myMap[magazine[i] - 'a'] --;
        }
        for(int it: myMap){
            if(it > 0){
                return false;
            }
        }
        return true;
    }
};

标程

增加一些判断,提前退出程序

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        int record[26] = {0};
        //add
        if (ransomNote.size() > magazine.size()) {
            return false;
        }
        for (int i = 0; i < magazine.length(); i++) {
            // 通过recode数据记录 magazine里各个字符出现次数
            record[magazine[i]-'a'] ++;
        }
        for (int j = 0; j < ransomNote.length(); j++) {
            // 遍历ransomNote,在record里对应的字符个数做--操作
            record[ransomNote[j]-'a']--;
            // 如果小于零说明ransomNote里出现的字符,magazine没有
            if(record[ransomNote[j]-'a'] < 0) {
                return false;
            }
        }
        return true;
    }
};

15. 三数之和

初始写法:过不了[0,0,0]这个样例

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        map<int, int> umap;
        set<vector<int>> ret;
        int len = nums.size();
        for(int i = 0; i < len; i++){
            umap.insert(pair<int, int>{nums[i], i});
        }
        for(int i = 0; i < len; i++){
            for(int j = i + 1; j < len; j++){
                if(umap.find(-nums[i]-nums[j]) != umap.end()){
                    int index = umap[-nums[i]-nums[j]];
                    if(i < index && j < index){
                        ret.insert({nums[i], nums[j], nums[index]});
                    }
                }
            }
        }
        vector<vector<int>> three;
        three.assign(ret.begin(), ret.end());
        return three;
    }
};

标程

要先排序

Class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;
        sort(nums.begin(), nums.end());
        // 找出a + b + c = 0
        // a = nums[i], b = nums[j], c = -(a + b)
        for (int i = 0; i < nums.size(); i++) {
            // 排序之后如果第一个元素已经大于零,那么不可能凑成三元组
            if (nums[i] > 0) {
                break;
            }
            if (i > 0 && nums[i] == nums[i - 1]) { //三元组元素a去重
                continue;
            }
            unordered_set<int> set;
            for (int j = i + 1; j < nums.size(); j++) {
                if (j > i + 2
                        && nums[j] == nums[j-1]
                        && nums[j-1] == nums[j-2]) { // 三元组元素b去重
                    continue;
                }
                int c = 0 - (nums[i] + nums[j]);
                if (set.find(c) != set.end()) {
                    result.push_back({nums[i], nums[j], c});
                    set.erase(c);// 三元组元素c去重
                } else {
                    set.insert(nums[j]);
                }
            }
        }
        return result;
    }
};

18. 四数之和

暂时放弃