872 字
4 分钟
算法 : 枚举
§枚举右,维护左
对于 双变量问题,例如两数之和 ,可以枚举右边的 ,转换成 单变量问题,也就是在 左边查找是否有 ,这可以用哈希表维护。
我把这个技巧叫做 枚举右,维护左。 讲解: 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)
- 3880. 两个值之间的最小绝对差值
- 2342. 数位和相等数对的最大和 - 力扣(LeetCode)
- 1128. 等价多米诺骨牌对的数量 - 力扣(LeetCode)
- 1679. K 和数对的最大数目 - 力扣(LeetCode)
- 面试题 16.24. 数对和 - 力扣(LeetCode)
- 219. 存在重复元素 II - 力扣(LeetCode)
- 2260. 必须拿起的最小连续卡牌数 - 力扣(LeetCode)
- 2001. 可互换矩形的组数 - 力扣(LeetCode)
- 2815. 数组中的最大数对和
- 3623. 统计梯形的数目 I
- 2364. 统计坏数对的数目
- 3805. 统计凯撒加密对数目
- 3371. 识别数组中的最大异常值
- 3761. 镜像对之间最小绝对距离
- 101057. 统计下标的相反奇偶性得分
§进阶
§枚举中间
对于有三个或者四个变量的问题,枚举中间的变量往往更好算。 为什么?比如问题有三个下标,需要满足 ,对比一下:
- 枚举 ,后续计算中还需保证 。
- 枚举 ,那么 和 自动被 隔开,互相独立,后续计算中无需关心 和 的位置关系。 所以枚举中间的变量更简单。
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; }};§遍历对角线
class Solution {public: vector<vector<int>> sortMatrix(vector<vector<int>>& grid) { int m = grid.size(), n = grid[0].size(); for(int k = 0; k < m + n; k++){ int min_j = max(n - k, 0); int max_j = min(m + n - 1 - k, n - 1); vector<int> a; for(int j = min_j; j <= max_j; j++){ a.push_back(grid[k + j - n][j]); } if(min_j > 0){ ranges::sort(a); }else{ ranges::sort(a,greater()); } for(int j = min_j; j <= max_j; j++){ grid[k + j - n][j] = a[j - min_j]; } } return grid; }};