591 字
3 分钟
算法 : 枚举
§0.1 枚举右,维护左
对于 双变量问题,例如两数之和 ,可以枚举右边的 ,转换成 单变量问题,也就是在 左边查找是否有 ,这可以用哈希表维护。
我把这个技巧叫做 枚举右,维护左。 讲解: 1. 两数之和 - 力扣(LeetCode)
class Solution {public: vector<int> twoSum(vector<int>& nums, int target) { unordered_map<int, int> idx; // 创建一个空哈希表 for (int j = 0; ; j++) { // 枚举 j // 在左边找 nums[i],满足 nums[i]+nums[j]=target auto it = idx.find(target - nums[j]); if (it != idx.end()) { // 找到了 return {it->second, j}; // 返回两个数的下标 } idx[nums[j]] = j; // 保存 nums[j] 和 j } }};- 1. 两数之和 - 力扣(LeetCode)
- 1512. 好数对的数目 - 力扣(LeetCode)
- 2441. 与对应负数同时存在的最大正整数 - 力扣(LeetCode)
- 121. 买卖股票的最佳时机 - 力扣(LeetCode)
- 2016. 增量元素之间的最大差值 - 力扣(LeetCode)
- 624. 数组列表中的最大距离 - 力扣(LeetCode)
- 2342. 数位和相等数对的最大和 - 力扣(LeetCode)
- 1128. 等价多米诺骨牌对的数量 - 力扣(LeetCode)
- 1679. K 和数对的最大数目 - 力扣(LeetCode)
- 面试题 16.24. 数对和 - 力扣(LeetCode)
- 219. 存在重复元素 II - 力扣(LeetCode)
- 2260. 必须拿起的最小连续卡牌数 - 力扣(LeetCode)
- 2001. 可互换矩形的组数 - 力扣(LeetCode)
- 2815. 数组中的最大数对和
- 3623. 统计梯形的数目 I
§0.2 枚举中间
对于有三个或者四个变量的问题,枚举中间的变量往往更好算。 为什么?比如问题有三个下标,需要满足 ,对比一下:
- 枚举 ,后续计算中还需保证 。
- 枚举 ,那么 和 自动被 隔开,互相独立,后续计算中无需关心 和 的位置关系。 所以枚举中间的变量更简单。
class Solution {public: int minimumSum(vector<int>& nums) { int n = nums.size(); vector<int> right(n); right[n - 1] = nums[n - 1]; for(int i = n - 2; i > 1; i--){ right[i] = min(nums[i], right[i + 1]); }
int ans = INT_MAX; int pre = nums[0]; for(int j = 1; j < n - 1; j++){ if(pre < nums[j] && nums[j] > right[j + 1]){ ans = min(ans, pre + nums[j] + right[j + 1]); } pre = min(pre, nums[j]); } return ans == INT_MAX ? -1 : ans; }};