当前位置: 首页 > news >正文

算法Day07 | 454.四数相加II,383. 赎金信,15. 三数之和, 18. 四数之和

Day07

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

454.四数相加II

题目链接:454.四数相加II
寻找两个数组之和,是否与另外两个数组之和有特定的关系。
因为数值可能跨度太大,选择使用下标表示为对应的数值大小,会很浪费内存空间。
target减去后两个数组之和的结果,是否存在与前两个数组之和组成的集合中。又要返回满足题意的次数,因此决定使用map而不是set

class Solution {
public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {unordered_map<int, int> map;for (auto& i: nums1) {for (auto& j: nums2) {map[i + j]++;//nums1 nums2之和存入map}}int cnt = 0;for (auto& i: nums3) {for (auto& j: nums4) {int target = 0 - (i + j);//查找target是否存在与map中if (map.find(target) != map.end()) {cnt += map[target];//target对应存在多少个,都加入}}}return cnt;}
};

383. 赎金信

题目链接:383. 赎金信
判断ransomNote中的字符是否出现在magazine中。

class Solution {
public:bool canConstruct(string ransomNote, string magazine) {if (ransomNote.size() > magazine.size()) {return false;}int record['z' - 'A' + 1] = {};//个数别查错了。+1for (auto& i : magazine) {record[i - 'A']++;}for (auto& i : ransomNote) {record[i - 'A']--;//出现就直接返回,不用在该循环之后再遍历recordif (record[i - 'A'] < 0) return false;}return true;}
};

15. 三数之和

题目链接:15. 三数之和
两个数之和,第三个数与目标值运算之后,是否出现在两个数之和中。
但是,时间复杂度为 O ( n 2 ) O(n^2) O(n2),且要去重操作。
选择使用双指针,注意去重操作。

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int> > ret;sort(nums.begin(), nums.end());for (int i = 0; i < nums.size(); i++) {if (nums[i] > 0) break;//剪枝。没有不影响结果//i指针的去重if (i > 0 && nums[i] == nums[i - 1]) continue;int left = i + 1, right = nums.size() - 1;while (left < right) {if (nums[i] + nums[left] + nums[right] > 0) {right--;} else if (nums[i] + nums[left] + nums[right] < 0) {left++;} else {ret.push_back(vector<int>{nums[i], nums[left], nums[right]});//left和right指针的去重。移动时,注意满足边界条件while (left < right && nums[left] == nums[left + 1])left++;while (left < right && nums[right] == nums[right - 1])right--;left++;right--;}}}return ret;}
};

其中

while (left < right && nums[left] == nums[left + 1]) left++;
while (left < right && nums[right] == nums[right - 1]) right--;left++;
right--;

前两行和后两行顺序不能调换。


18. 四数之和

题目链接: 18. 四数之和
三数之和再多套一个遍历。不用哈希理由三数之和。
注意剪枝条件不同于三数之和,因为三数的target是0

class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int>> ret;sort(nums.begin(), nums.end());//排序for (int k = 0; k < nums.size(); k++) {if (nums[k] > target && nums[k] >= 0) break;//剪枝if (k > 0 && nums[k] == nums[k - 1]) continue;//k去重for (int i = k + 1; i < nums.size(); i++) {if (nums[k] + nums[i] > target && nums[k] + nums[i] >= 0) break;//剪枝。k+i是一个整体if (i > k + 1 && nums[i] == nums[i - 1]) continue;//i去重int left = i + 1, right = nums.size() - 1;while (left < right) {if ((long) nums[k] + nums[i] + nums[left] + nums[right] > target) right--;else if ((long) nums[k] + nums[i] + nums[left] + nums[right] < target) left++;else {ret.push_back(vector<int>{nums[k], nums[i], nums[left], nums[right]});while (left < right && nums[left] == nums[left + 1]) left++;//left去重while (left < right && nums[right] == nums[right - 1]) right--;//right去重right--;left++;}}}}return ret;}
};
if ((long) nums[k] + nums[i] + nums[left] + nums[right] > target)

long是因为nums数组中的元素超过int范围,导致溢出了。

http://www.lryc.cn/news/68056.html

相关文章:

  • ps抠图、抠头发去背景等
  • 计算机组成原理基础练习题第一章
  • [PyTorch][chapter 34][池化层与采样]
  • Java进阶-字符串的使用
  • 接口自动化框架对比 | 质量工程
  • 谷歌浏览器network error解决方法
  • 自动化测试如何做?接口自动化测试框架必备的9个功能,测试老鸟总结...
  • ANR原理篇 - ANR原理总览
  • 新版Mamba体验超快的软件安装
  • LDAP配置与安装
  • 1-Linux环境安装JDK
  • 通胀数据回落助金价小幅回升
  • 正则表达式的基本语法以及技巧和示例
  • 蓝牙耳机怎么挑选?小编分享2023畅销蓝牙耳机排行榜
  • Linux快照太有趣了!
  • 【改进粒子群优化算法】自适应惯性权重粒子群算法(Matlab代码实现)
  • ROS 下 激光扫描仪 YDLidar-G4 使用
  • 智能边缘:数字化时代的关键战略之一
  • EasyRecovery16中文最新版电脑数据恢复软件下载使用教程
  • 什么是鉴权?这些postman鉴权方式你又知道多少?
  • 最新的经典mysql面试题及答案
  • 算法修炼之练气篇——练气十九层
  • 记录一次Windows7操作系统渗透测试
  • 承诺协议:定义 构造
  • 二、easyUI中的layout(布局)组件
  • MySQL---聚合函数、字符串函数、数学函数、日期函数
  • 边缘计算盒子有哪些?边缘计算应用场景
  • Linux内核(十四)Input 子系统详解 IV —— 配对的input设备与input事件处理器 input_register_handle
  • Vue2.x源码解析(三)
  • 全面理解守护进程的基础概念,以及如何创建一个守护进程(系列文章第三篇)