11.11 LeetCode 题目汇总与解题思路

题目一:454. 四数相加 II

解法:分组哈希法

复制代码
class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        unordered_map<int, int> map;
        int ans = 0;
        // 计算 nums1 + nums2 的所有和
        for (int x : nums1) {
            for (int y : nums2) {
                map[x + y]++;
            }
        }
        // 查找 nums3 + nums4 的补数
        for (int x : nums3) {
            for (int y : nums4) {
                ans += map[-(x + y)];
            }
        }
        return ans;
    }
};

核心思路:将4个数组分成两组,降低时间复杂度从O(n⁴)到O(n²)

题目二:383. 赎金信

解法1:哈希表法(你的错误版本)

复制代码
class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        unordered_map<char, int> map;
        for (auto elem : ransomNote) {  // 错误:先统计需求
            map[elem]++;
        }
        for (auto elem : magazine) {    // 再减去供给
            map[elem]--;
            if (map[elem] < 0) return false;  // 逻辑错误
        }
        return true;
    }
};

解法2:哈希表法(正确版本)

复制代码
class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        unordered_map<char, int> map;
        // 先统计供给(magazine)
        for (auto elem : magazine) {
            map[elem]++;
        }
        // 再检查需求(ransomNote)
        for (auto elem : ransomNote) {
            map[elem]--;
            if (map[elem] < 0) return false;  // 供给不足
        }
        return true;
    }
};

解法3:数组计数法(最优)

复制代码
class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        if (ransomNote.size() > magazine.size()) return false;
        int count[26] = {0};
        
        // 统计供给
        for (char c : magazine) {
            count[c - 'a']++;
        }
        // 检查需求
        for (char c : ransomNote) {
            if (count[c - 'a'] <= 0) return false;
            count[c - 'a']--;
        }
        return true;
    }
};

题目三:15. 三数之和

解法:排序 + 双指针

复制代码
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        ranges::sort(nums);  // 关键:先排序
        vector<vector<int>> ans;
        int n = nums.size();
        
        for (int i = 0; i < n - 2; i++) {
            int x = nums[i];
            // 去重
            if (i && x == nums[i - 1]) continue;
            // 剪枝优化
            if (x + nums[i + 1] + nums[i + 2] > 0) break;
            if (x + nums[n - 2] + nums[n - 1] < 0) continue;
            
            int j = i + 1, k = n - 1;  // 双指针
            while (j < k) {
                int s = x + nums[j] + nums[k];
                if (s > 0) k--;
                else if (s < 0) j++;
                else {
                    ans.push_back({x, nums[j], nums[k]});
                    // 去重
                    for (k--; k > j && nums[k] == nums[k + 1]; k--);
                    for (j++; j < k && nums[j] == nums[j - 1]; j++);
                }
            }
        }
        return ans;
    }
};

题目四:18. 四数之和

解法:排序 + 双指针(三数之和的扩展)

复制代码
class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        ranges::sort(nums);
        vector<vector<int>> ans;
        int n = nums.size();
        
        for (int a = 0; a < n - 3; a++) {
            long long x = nums[a];
            // 去重
            if (a && x == nums[a - 1]) continue;
            // 剪枝优化
            if (x + nums[a + 1] + nums[a + 2] + nums[a + 3] > target) break;
            if (x + nums[n - 3] + nums[n - 2] + nums[n - 1] < target) continue;
            
            for (int b = a + 1; b < n - 2; b++) {
                long long y = nums[b];
                // 去重
                if (b > a + 1 && y == nums[b - 1]) continue;
                // 剪枝优化
                if (x + y + nums[b + 1] + nums[b + 2] > target) break;
                if (x + y + nums[n - 2] + nums[n - 1] < target) continue;
                
                int c = b + 1, d = n - 1;  // 双指针
                while (c < d) {
                    long long s = x + y + nums[c] + nums[d];
                    if (s > target) d--;
                    else if (s < target) c++;
                    else {
                        ans.push_back({(int)x, (int)y, nums[c], nums[d]});
                        // 去重
                        for (c++; c < d && nums[c] == nums[c - 1]; c++);
                        for (d--; d > c && nums[d] == nums[d + 1]; d--);
                    }
                }
            }
        }
        return ans;
    }
};

核心技巧总结

技巧 适用场景 代表题目 时间复杂度
分组哈希 多个数组组合问题 四数相加II O(n²)
数组计数 字符统计、小范围数值 赎金信 O(n)
排序+双指针 多数和问题、需要去重 三数之和、四数之和 O(n²)~O(n³)
剪枝优化 有序数组的搜索问题 三/四数之和 大幅提升效率

关键区别

四数相加II vs 三/四数之和:

  • 四数相加II:四个独立数组,只求个数 → 分组哈希
  • 三/四数之和:单个数组,需要具体解且去重 → 排序+双指针

赎金信的关键:

  • 统计顺序:先统计供给(magazine),再检查需求(ransomNote)
  • 数据结构:优先使用数组而非哈希表(字符有限)

解题模板

多数和问题模板:

复制代码
1. 排序数组
2. 外层循环固定第一个数(去重)
3. 剪枝优化
4. 内层使用双指针查找
5. 找到解后双指针去重

分组哈希模板:

复制代码
1. 将问题分成两组
2. 计算第一组的所有可能(存入map)
3. 在第二组中查找补数
相关推荐
deepseek2312 小时前
OpenAI三项科学发现拆解:3-SAT亚指数算法挑战ETH,AI科学声明的验证流水线怎么搭
人工智能·算法·openai
梦帮科技13 小时前
基于幺正李代数连续归一化流的混合量子生成模型 (HQNN-Flow) 完整技术指南(上部分)
网络·人工智能·算法·量子计算
青少儿编程课堂13 小时前
蓝桥杯青少组 + 全国青少年信息素养大赛 + 电子学会图形化考级|校园推箱子大挑战解析
c++·python·算法·bfs·信息学竞赛
ynchyong13 小时前
培养程序化思维
leetcode·程序化思维·刷题经验
荆棘鸟智能13 小时前
河道采砂船识别与轨迹追踪怎么做?检测、跟踪与电子围栏实战思路
人工智能·算法·目标检测
DFT计算杂谈14 小时前
GSAS-II X 射线衍射(XRD)数据转换为对分布函数(PDF,Pair Distribution Function)
算法·机器学习·pdf
绕灵儿14 小时前
火灾检测-应用场景-YOLO训练记录
人工智能·算法
YLCHUP15 小时前
【模拟&STL】题解:AT_abc203_e [ABC203E] White Pawn_基础算法_数据结构_STL模板库_AtcoderABC_C++算法竞赛
数据结构·c++·算法·leetcode·动态规划·哈希算法·近邻算法
啊啊啊啊啊!!!!15 小时前
【c++】⽤哈希表封装myunordered_map和myunordered_set
数据结构·哈希算法·散列表
(●—●)橘子……15 小时前
力扣 第525场周赛 练习理解
数据结构·python·学习·算法·leetcode