您的位置:首页 > 娱乐 > 明星 > 就在刚刚湖北传来疫情大消息_怎么在网上销售_百度排名规则_小吴seo博客

就在刚刚湖北传来疫情大消息_怎么在网上销售_百度排名规则_小吴seo博客

2025/2/26 10:04:30 来源:https://blog.csdn.net/Hamdh/article/details/144211297  浏览:    关键词:就在刚刚湖北传来疫情大消息_怎么在网上销售_百度排名规则_小吴seo博客
就在刚刚湖北传来疫情大消息_怎么在网上销售_百度排名规则_小吴seo博客

题目引用


  1. 四数相加II
  2. 赎金信
  3. 三数之和
  4. 四数之和

1.四数相加II


给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
示例 1:
输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
示例 2:
输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]

我们来分析一下题目,题目给出了四个元组,要我们从各组中取一个元素,使其相加为0。这道题其实就是昨天两数之和的变形,只不过对象从一个数组变成了四个,和从两个变成了四个且为固定值0。那么我们只要模拟其过程,很容易就能写出代码。
首先将前两个数组相加成为两数之和的第一个数,再在后两个数组中寻找与其相加为0的两个数成为第二个数,找到就使结果++
来看代码:

int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {unordered_map<int,int> map;for(auto a:nums1){for(auto b:nums2){map[a+b]++;}}int Count=0;for(auto c:nums3){for(auto d:nums4){if(map.find(0-(c+d))!=map.end()){Count+=map[0-(c+d)];}}}return Count;}

我们用map记录第一个数出现的次数及key值,第二次循环查找其的相反数就能找到啦,找到就将结果加上出现次数即能得到最终结果。

2.赎金信


给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。
如果可以,返回 true ;否则返回 false 。
magazine 中的每个字符只能在 ransomNote 中使用一次。
示例 1:
输入:ransomNote = “a”, magazine = “b”
输出:false
示例 2:
输入:ransomNote = “aa”, magazine = “ab”
输出:false
示例 3:
输入:ransomNote = “aa”, magazine = “aab”
输出:true

大家看到这道题是不是有一种熟悉的感觉,跟昨天的有效的字母异位词几乎一样的解法,如果有不懂的同学可以看看我昨天的博客,这里我就直接放出代码啦~

bool canConstruct(string ransomNote, string magazine) {if(ransomNote.size()>magazine.size()) return false;vector<int> cnt(26);for(auto &c:magazine) cnt[c-'a']++;for(auto &c:ransomNote){cnt[c-'a']--;if(cnt[c-'a']<0) return false;}return true;}

3.三数之和


给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
示例 3:
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

这里我们可以看到,在这里的哈希是不太好用的,因为我们需要每次遍历数组的过程中初始化一个哈希表用作映射和去重的"中介",这样在整个循环去重剪枝的过程中显得较为鸡肋且可能影响后续的思路与操作了,属实是哈希的困难点和局限性,所以我们可以换个思路,使用双指针算法来解决这个问题~
我们来看,首先我们可以先对数组排一下序,方便后续去重的操作。然后建立一个for循环,并对nums[i]位置的数进行去重和剪枝操作,再设立leftright两个指针分别指向i+1位置和数组的末尾,将nums[i],nums[left],nums[right]相加,>0--right<0++left,等于就将三个数插入结果数组中,接着对right和left位置的数进行去重,缩小区间。最后返回答案。

vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> result;sort(nums.begin(),nums.end());for(int i=0;i<nums.size();i++){if(nums[i]>0) return result;if(i>0&&nums[i]==nums[i-1]) continue;int left=i+1;int right=nums.size()-1;while(right>left){if (nums[i] + nums[left] + nums[right] > 0) right--;else if (nums[i] + nums[left] + nums[right] < 0) left++;else {result.push_back(vector<int>{nums[i], nums[left], nums[right]});while (right > left && nums[right] == nums[right - 1]) right--;while (right > left && nums[left] == nums[left + 1]) left++;right--;left++;}}}return result;}

4.四数之和


给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
示例 1:
输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
示例 2:
输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]

如果学会上一道题的话,那么这道题直接copy上一道题的代码再加上一次循环和剪枝就可以AC了。程序员的快乐~hhh

vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int>> result;sort(nums.begin(),nums.end());for(int i=0;i<nums.size();i++){if(nums[i]>target&&nums[i]>=0) break;if(i>0&&nums[i]==nums[i-1]) continue;for(int j=i+1;j<nums.size();j++){if (nums[i] + nums[j] > target && nums[i] + nums[j] >= 0) break;// 对nums[j]去重if (j > i + 1 && nums[j] == nums[j - 1]) continue;int left=j+1,right=nums.size()-1;while(left<right){if((long)nums[i]+nums[j]+nums[left]+nums[right]>target) right--;else if((long)nums[i]+nums[j]+nums[left]+nums[right]<target) left++;else{result.push_back(vector<int>{nums[i],nums[j],nums[left],nums[right]});while(left<right&&nums[right]==nums[right-1]) right--;while(left<right&&nums[left]==nums[left+1]) left++;left++;right--;}}}}return result;}

总结


今天我们复习了昨天的知识,并且认识到就算是需要集合的题目也不一定非要使用哈希,而是使用其他的方法来绕开相应的困难点,此时前段时间的数组相关算法就显示出它的魅力了。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com