首页 > 编程语言 >算法刷题 Day 7 | 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

算法刷题 Day 7 | 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

时间:2023-01-03 22:44:35浏览次数:66  
标签:vector 四数 15 nums int 三数 right 哈希 left

从今天开始,下定决心正式把语言转为C++,之后也会用C++重新把前几天的题解再写一遍。加油

454.四数相加II

建议:本题是 使用map 巧妙解决的问题,好好体会一下 哈希法 如何提高程序执行效率,降低时间复杂度,当然使用哈希法 会提高空间复杂度,但一般来说我们都是舍空间 换时间, 工业开发也是这样。

题目链接/文章讲解/视频讲解:https://programmercarl.com/0454.%E5%9B%9B%E6%95%B0%E7%9B%B8%E5%8A%A0II.html

Tips:这里使用的是unordered_map,同时需要注意哈希表判断有无某一个元素的方式umap.find(a)!=umap.end()

我的题解:

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        unordered_map<int, int> umap;
        for(int i : nums1){
            for(int j : nums2){
                umap[i+j]++;
            }
        }

        int result = 0;
        for(int i : nums3){
            for(int j : nums4){
                // 哈希表判断有无某一个元素的方式
                if(umap.find(-(i+j))!=umap.end()){
                    result+=umap[i+j];
                }
            }
        }
        return result;
    }
};

383. 赎金信

建议:本题 和 242.有效的字母异位词 是一个思路 ,算是拓展题

题目链接/文章讲解:https://programmercarl.com/0383.%E8%B5%8E%E9%87%91%E4%BF%A1.html

Tips:这个题还是用数组作为哈希表即可

我的题解:

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        // 将数组初始化为0
        int history[26] = {0};
        for(int i=0;i<magazine.size();i++){
            history[magazine[i] - 'a']++;
        }
        for(int i=0;i<ransomNote.size();i++){
            if(history[ransomNote[i] - 'a'] <= 0){
                return false;
            }
            else{
                history[ransomNote[i] - 'a']--;
            }
        }
        return true;
    }
};

15. 三数之和

建议:本题虽然和 两数之和 很像,也能用哈希法,但用哈希法会很麻烦,双指针法才是正解,可以先看视频理解一下 双指针法的思路,文章中讲解的,没问题 哈希法很麻烦。

题目链接/文章讲解/视频讲解:https://programmercarl.com/0015.%E4%B8%89%E6%95%B0%E4%B9%8B%E5%92%8C.html

Tips:这道题虽然放在哈希表专题里面,但是用哈希表来做会非常复杂,主要是去重操作太难写了,说实话看代码看了很久也没太看懂去重的思路是什么,所以应该直接采用双指针法写出题解。

我的题解:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;
        sort(nums.begin(),nums.end());
        for(int i = 0;i<nums.size();i++){
            if(i > 0 && nums[i] == nums[i-1]){
                continue;
            }
            int left = i+1;
            int right = nums.size() -1;
            while(left<right){
                if(nums[i] + nums[left] + nums[right] == 0){
                    result.push_back(vector<int>{nums[i], nums[left], nums[right]});
                    while(left < right && nums[right] == nums[right-1]){
                        right--;
                    }
                    while(left < right && nums[left] == nums[left + 1]){
                        left++;
                    }
                    right--;
                    left++;
                }
                else if(nums[i] + nums[left] + nums[right] < 0){
                    left++;
                }
                else{
                    right--;
                }
            }
        }
        return result;
    }
};

18. 四数之和

建议: 要比较一下,本题和 454.四数相加II 的区别,为什么 454.四数相加II 会简单很多,这个想明白了,对本题理解就深刻了。 本题 思路整体和 三数之和一样的,都是双指针,但写的时候 有很多小细节,需要注意,建议先看视频。

题目链接/文章讲解/视频讲解:https://programmercarl.com/0018.%E5%9B%9B%E6%95%B0%E4%B9%8B%E5%92%8C.html

Tips:逻辑上其实就是比三数之和多了一层for循环,时间复杂度也高了一个数量级,但是思想是一样的,仍然需要注意去重的操作。

我的题解:

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> result;
        sort(nums.begin(),nums.end());
        for(int i = 0; i < nums.size();i++){
            if(i > 0 && nums[i] == nums[i-1]){
                continue;
            }
            for(int j = i + 1; j < nums.size(); j++){
                if(j > i + 1 && nums[j] == nums[j-1]){
                    continue;
                }
                int sum = nums[i] + nums[j];
                int left = j+1;
                int right = nums.size() -1;
                while(left< right){
                    // nums[k] + nums[i] + nums[left] + nums[right] > target 会溢出
                    if((long)sum + nums[left] + nums[right] == target){
                        result.push_back(vector<int>{nums[i],nums[j],nums[left],nums[right]});
                        while(left<right && nums[left] == nums[left+1]){
                            left++;
                        }
                        while(left<right && nums[right] == nums[right-1]){
                            right--;
                        }
                        left++;
                        right--;
                    }
                    else if((long)sum + nums[left] + nums[right] < target){
                        left++;
                    }
                    else{
                        right--;
                    }
                }
            }
        }
        return result;
    }
};

 

标签:vector,四数,15,nums,int,三数,right,哈希,left
From: https://www.cnblogs.com/GavinGYM/p/17023596.html

相关文章