当前位置:   article > 正文

代码随想录算法训练营第七天|454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

代码随想录算法训练营第七天|454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

今天的题好难,写了很长时间,这还是在公交车上提前看过了的

454. 四数相加 II

给你四个整数数组 nums1nums2nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:

  • 0 <= i, j, k, l < n
  • nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

示例 1:

输入:nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2]
输出:2
解释:
两个元组如下:
1. (0, 0, 0, 1) -> nums1[0] + nums2[0] + nums3[0] + nums4[1] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -> nums1[1] + nums2[1] + nums3[0] + nums4[0] = 2 + (-1) + (-1) + 0 = 0

示例 2:

输入:nums1 = [0], nums2 = [0], nums3 = [0], nums4 = [0]
输出:1
  1. class Solution {
  2. public:
  3. int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
  4. unordered_map<int,int> result;
  5. for(int numsa : nums1)
  6. {
  7. for(int numsb : nums2)
  8. {
  9. result[numsa + numsb]++;
  10. }
  11. }
  12. int count = 0;
  13. for(int numsa : nums3)
  14. {
  15. for(int numsb : nums4)
  16. {
  17. if(result.find(-numsa-numsb) != result.end())
  18. {
  19. //count ++;这样写是错的,少了重复情况
  20. count += result[-numsa-numsb];
  21. }
  22. }
  23. }
  24. return count;
  25. }
  26. };

383. 赎金信

给你两个字符串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

简单

  1. class Solution {
  2. public:
  3. bool canConstruct(string ransomNote, string magazine)
  4. {
  5. if(ransomNote.length() > magazine.length()) return false;
  6. unordered_map<int,int> smap;
  7. for(int i = 0;i < magazine.length();i++)
  8. {
  9. smap[magazine[i]]++;
  10. }
  11. for(int i = 0; i <ransomNote.length(); i++)
  12. {
  13. if(smap[ransomNote[i]] <= 0)
  14. {
  15. return false;
  16. }
  17. smap[ransomNote[i]]--;
  18. }
  19. return true;
  20. }
  21. };

15. 三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != 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 。

我真的服了,为什么要这样才可以运行,好好看看注释掉的地方

  1. class Solution {
  2. public:
  3. vector<vector<int>> threeSum(vector<int>& nums)
  4. {
  5. vector<vector<int>> result;
  6. sort(nums.begin(),nums.end());
  7. int i = 0, j = 0 ,k = nums.size() - 1;//双指针法
  8. for( ;i < nums.size() - 2; i++)
  9. {
  10. if(i > 0 && nums[i] == nums[i - 1]) continue;
  11. j = i + 1 ;
  12. k = nums.size() - 1;
  13. //注意if别放到while里了
  14. while(j < k)
  15. {
  16. if(nums[i] + nums[j] + nums[k] == 0)
  17. {
  18. //result.push_back({nums[i],nums[j],nums[k]});这样是不能一次性压入的,需要使用vector<vector<int>>才行
  19. result.push_back({nums[i],nums[j],nums[k]});
  20. //需要加上处理jk的方法,不然会一直在这里卡住
  21. //并且这里必须加上while来跳过重复三元组,当然了之前也要加上,因为三元组中不允许有重复元素
  22. while(j < k &&(nums[j] == nums[j+1])) j++;
  23. while(j < k &&(nums[k] == nums[k-1])) k--;//降重是必须的,不然会有重复
  24. j++;
  25. //k--;
  26. }
  27. else if(nums[i] + nums[j] + nums[k] > 0)
  28. {
  29. k--;
  30. }
  31. else//(nums[i] + nums[j] + nums[k] < 0),为什么这里注释了才可以运行,莫名其妙
  32. {
  33. j++;
  34. }
  35. }
  36. }
  37. return result;
  38. }
  39. };

18. 四数之和

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

  • 0 <= a, b, c, d < n
  • abc 和 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]]

服了,这个题好多细节,去重,long都需要关注

  1. class Solution {
  2. public:
  3. vector<vector<int>> fourSum(vector<int>& nums, int target)
  4. {
  5. vector<vector<int>> result;
  6. //false1.push_back(vector<int>());
  7. sort(nums.begin(),nums.end());
  8. int i,j,left,right;
  9. if(nums.size() < 4) return result;
  10. for(i = 0;i < nums.size() - 3 ;i++)
  11. {
  12. if(i > 0 && nums[i] == nums[i-1]) continue;
  13. for(j = i + 1 ;j < nums.size() - 2; j++)
  14. {
  15. if(j > i + 1 &&nums[j] == nums[j-1]) continue;
  16. //注意这两部的降重操作,很关键,别忘了
  17. left = j + 1;
  18. right = nums.size() - 1;
  19. while(left < right)
  20. {
  21. //int sum = nums[i] + nums[j] + nums[left] + nums[right];
  22. //注意这里需要加上long,防止计算超出int范围
  23. if((long)nums[i] + nums[j] + nums[left] + nums[right] == target)
  24. {
  25. result.push_back({nums[i],nums[j],nums[left],nums[right]});
  26. while(left < right && nums[left] == nums[left+1]) left++;
  27. while(left < right && nums[right] == nums[right-1]) right--;
  28. left++;
  29. right--;
  30. }
  31. else if((long)nums[i] + nums[j] + nums[left] + nums[right] > target) right--;
  32. else if((long)nums[i] + nums[j] + nums[left] + nums[right] < target) left++;
  33. }
  34. }
  35. }
  36. return result;
  37. }
  38. };

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/943345
推荐阅读
相关标签
  

闽ICP备14008679号