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

哈希表-赎金信三数之和四数之和

哈希表

赎金信(leetcode.383)

给你两个字符串:ransomNotemagazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。

如果可以,返回 true ;否则返回 false

并不困难,因为字母都是小写的,那么可以定义一个hash[26]作为映射,先看看magazine中的库存有什么字符,然后遍历ransomNote,如果遍历完,字符数量有小于0出现,表示没有相应的字符,返回false

class Solution {
public:bool canConstruct(string ransomNote, string magazine) {if (ransomNote.size() > magazine.size()) {return false;} // 可以先判断一下是否满足库存字符大于需要字符int hash[26] = {0};for(const auto& c : magazine){++hash[c - 'a'];}for(const auto& c : ransomNote){--hash[c - 'a'];if(hash[c - 'a'] < 0){return false;}}return true;}
};

三数之和(梦破碎的地方)leetcode.15

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != kj != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

这题其实挺有难度的,而且哈希表不好求,还是来看一下思路:

索引不能相同,元素之和为0,而且组成的三元组不能重复;也就是说a+b+c=0,再进行遍历时候,a不可重复,b不可重复,那么c = -(a+b)自然不重复。

首先,我们需要对数组进行排序,使用sort对其进行升序排序,得到新的nums;开始遍历数组,先固定住其中一个i,然后再次进行遍历j,那么这里为了保证a不重复,那么就需要进行判断了,如果nums[i] == nums[i-1],这就说明a重复了,得跳过;后面开始找b,那么我们需要一个哈希表存放目标值c,因为通过b可以知道目标值c=-(a+b),所以我们需要将目标值放入集合,如果后面遍历发现目标值就达到条件了,但是这里达到条件后需要注意细节了,因为b也有可能重复,所以说还需要进行判断,while(j < n-1 && nums[j] == nums[j+1]) ++j;如果目标数后面一位依然是目标数,那么就要跳过了;最后返回满足题目的所有三元组。

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> result;std::sort(nums.begin(),nums.end());int n = nums.size();if(n < 3) return result;for(int i = 0; i < n; ++i){// 如果排好序的数组遍历到的当前数大于0,就退出了if(nums[i] > 0) break;// 如果遍历到的数和上一轮一样,也不行,因为要不重复// 上一轮已经选择了这个元素了if(i > 0 && nums[i] == nums[i-1]) continue;unordered_set<int> set_; // 存储第三个数for(int j = i+1; j < n; ++j){int target = -nums[i] - nums[j];if(set_.find(nums[j]) != set_.end()){result.push_back({nums[i], nums[j], target});while(j < n-1 && nums[j] == nums[j+1]) ++j;}set_.insert(target);}}return result;}
};

双指针法

大概思路差不多,也是先固定一个值,然后定义两个指针,一个left,一个right,可以通过判断三者之和sum,来调整双指针指向,如果大了,说明right指向太大,--right,小了,++left;如果满足条件,就说明找到目标的三元组了,找到后续需要再进行重复性判断的问题,外层循环已经解决了a的重复,需要对left、right进行重复性判断,通过while来实现,满足前提条件,left<right下,while(left < right && nums[left] == nums[left+1]),++left,如果没有重复,正常++left,--right

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> result;std::sort(nums.begin(),nums.end());int n = nums.size();if(n < 3) return result;for(int i = 0; i < n; ++i){if(nums[i] > 0) break;if(i > 0 && nums[i] == nums[i-1]) continue;int left = i+1, right = n-1;while(left < right){int sum = nums[i] + nums[left] + nums[right]; if(sum > 0) --right;else if(sum < 0) ++left;else{result.push_back({nums[i],nums[left],nums[right]});while(left < right && nums[left] == nums[left+1]) ++left; // 不写left < right 会出现索引越界错误while(left < right && nums[right] == nums[right-1]) --right;++left; // 正常情况--right;}}}return result;}
};

四数之和(leetcode.18)

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

  • 0 <= a, b, c, d < n
  • abcd 互不相同
  • nums[a] + nums[b] + nums[c] + nums[d] == target

你可以按 任意顺序 返回答案

没啥,前面三数之和会了后,这题并无大问题

class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {sort(nums.begin(),nums.end());vector<vector<int>> res;int n = nums.size();if(n < 4) return res;for(int i = 0; i < n; ++i){if(nums[i] > 0 && nums[i] > target) break;if(i > 0 && nums[i] == nums[i-1]) continue; // 保证a不重复for(int j = i+1; j < n; ++j){if(static_cast<long long>(nums[i] + nums[j]) > target && target > 0) break; if(j > i+1 && nums[j] == nums[j-1]) continue; // 保证b不重复int left = j+1, right = n-1;while(left < right){long long sum = static_cast<long long>(nums[i]) + nums[j] + nums[left] + nums[right];if(sum > target){--right;} else if(sum < target){++left;} else {res.push_back({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;}}}}return res;}
};
http://www.jsqmd.com/news/446696/

相关文章:

  • java 分割字符保留分割符
  • 2026年制造企业选型必看:中国精益生产咨询公司适配指南与核心价值评估。 - 品牌推荐
  • picgo+码云配置markdown图床
  • Class文件解读
  • Windows 10 下安装 Docker Desktop
  • 2026年用户口碑最佳的精益管理咨询公司推荐:五家机构服务实效与客户反馈对比 - 品牌推荐
  • 2026年制造企业选型必看:生产现场管理咨询公司适配指南与核心能力拆解 - 品牌推荐
  • 2026年企业增长必看:中国营销管理咨询公司选型指南与精准适配路径 - 品牌推荐
  • 2026年品牌咨询公司深度测评:基于企业增长实效的三维价值解析 - 品牌推荐
  • 2026年制造企业选型必看:精益管理咨询公司适配指南与核心价值点实测 - 品牌推荐
  • 2026年用户口碑最佳全屋定制品牌推荐:五款真实案例与设计服务对比 - 十大品牌推荐
  • 2026年企业选型必看:中国营销管理咨询公司适配指南与核心能力拆解 - 品牌推荐
  • 2026年生产现场管理咨询公司权威榜单:基于实战效果与客户复购率的深度排位赛 - 品牌推荐
  • 2026年中小企业品牌升级必看:五大品牌咨询公司适配指南与选型实测 - 品牌推荐
  • 数字化赋能产业升级:2026年主流企业管理咨询机构竞争力与格局解析 - 十大品牌推荐
  • 2026年用户口碑最佳的精益管理咨询公司推荐:五家机构服务实效与案例对比 - 品牌推荐
  • 2026年企业家口碑推荐:十大企业管理咨询公司服务效果与案例实证 - 十大品牌推荐
  • 宠物眼疾莫慌,福州这些眼科专家服务贴心,宠物眼科/狗狗义眼植入/猫咪眼睑外翻手术/猫咪义眼植入,宠物眼科医生推荐榜单 - 品牌推荐师
  • 2026年用户口碑实证:中国营销管理咨询公司服务效果与客户价值全面对比 - 品牌推荐
  • 2026年木作品牌深度测评:基于材质创新与智能高定的五维竞争力全解析 - 品牌推荐
  • 2026年家装决策必看:全屋定制品牌选型指南与精准适配场景实测 - 十大品牌推荐
  • 2026年北京家居商场选型指南:聚焦局改、适老与全屋智能的场景化适配攻略 - 品牌推荐
  • 2026年上海离婚律所选型指南:基于核心需求与案件复杂度的精准适配分析 - 品牌推荐
  • 2026年品牌咨询公司权威榜单发布:五大机构战略定位与落地能力深度评测 - 品牌推荐
  • 2026年用户口碑实证的上海离婚律所推荐:五家机构真实服务体验与案例对比 - 品牌推荐
  • 【深度解析】激光切管机:技术原理、工业价值与实践应用 - 速递信息
  • 2026年家庭置家必看:北京家居商场选型指南与四大核心价值适配分析 - 品牌推荐
  • 2026年用户口碑实证:上海离婚律所服务满意度与实战案例效果全面对比 - 品牌推荐
  • SwiftOCR与GPUImage:构建iOS端高性能OCR应用的黄金组合
  • 不是洗稿,是学术化重构——百考通降重+降AI,保观点、保逻辑、保原创