首页 > 其他分享 >代码随想录day7 ● 454.四数相加II ● 383. 赎金信 ● 15. 三数之和 ● 18. 四数之和 ● 总结

代码随想录day7 ● 454.四数相加II ● 383. 赎金信 ● 15. 三数之和 ● 18. 四数之和 ● 总结

时间:2022-09-30 19:13:05浏览次数:88  
标签:ransomNote 四数 15 nums int 随想录 ++ right left

454. 四数相加 II

暴力解法(超出时间限制):

 1 class Solution {
 2 public:
 3     int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
 4         int n = nums1.size();
 5         int result = 0;
 6         for (int i = 0; i < n; i++){
 7             for (int j = 0; j < n; j++){
 8                 for (int k = 0; k < n; k++){
 9                     for (int z = 0; z < n; z++){
10                         if (nums1[i] + nums2[j] + nums3[k] + nums4[z] == 0){
11                             result++;
12                         }
13                     }
14                 }
15             }
16         }
17         return result;
18     }
19 };

哈希法:

第一步:定义一步unordered_map,key放a和b两数之和,value放a和b两数之和出现的次数;

第二步:遍历前两数组,记录两个数组元素之和以及出现的次数,umap[a+b]++;

第三步:遍历后两数组,记录(0 - (c+d))出现的次数;

第四步:count += umap[0 - (c + d)];

第五步:返回count;

 1 class Solution {
 2 public:
 3     int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
 4         //创建unordered_map用于保存nums1[i] + nums2[j]出现的次数
 5         //key用于记录a + b的值,val用于记录a + b出现的次数
 6         unordered_map<int, int> umap;
 7         //用于记录a + b = - (c + d)的次数
 8         int count = 0;
 9         //用于记录a + b出现的次数
10         for (int a : A){
11             for (int b : B){
12                 //记录出现次数
13                 umap[a + b]++;
14             }
15         }
16         //判断c + d出现的次数
17         for (int c : C){
18             for (int d : D){
19                 if (umap.find(0 - (c + d)) != umap.end()){
20                     count += umap[0 - (c + d)];
21                 }
22             }
23         }
24         return count;
25     }
26 };

383. 赎金信

自己写的类似242.有效的字母异位词的解法:

 1 class Solution {
 2 public:
 3     bool canConstruct(string ransomNote, string magazine) {
 4         int res[26] = {0};
 5         //记录ransomNote中字母出现的次数
 6         for (int i = 0; i < ransomNote.size(); i++){
 7             res[ransomNote[i] - 'a']--;
 8         }
 9         //减去magazine中字母出现的次数
10         for (int i = 0; i < magazine.size(); i++){
11             res[magazine[i] - 'a']++;
12         }
13         //判断数组中的每个数是否大于0
14         for (int i = 0; i < 26; i++){
15             if(res[i] < 0){
16                 return false;
17             }
18         }
19         return true;
20     }
21 };

卡哥暴力解法:

 1 // 时间复杂度: O(n^2)
 2 // 空间复杂度:O(1)
 3 class Solution {
 4 public:
 5     bool canConstruct(string ransomNote, string magazine) {
 6         //遍历两个数组,当magazine当中出现ransomNote中的字母消去ransomNote中的该字母
 7         for (int i = 0; i < magazine.length(); i++) {
 8             for (int j = 0; j < ransomNote.length(); j++) {
 9                 // 在ransomNote中找到和magazine相同的字符
10                 if (magazine[i] == ransomNote[j]) {
11                     ransomNote.erase(ransomNote.begin() + j); // ransomNote删除这个字符
12                     break;
13                 }
14             }
15         }
16         // 如果ransomNote为空,则说明magazine的字符可以组成ransomNote
17         if (ransomNote.length() == 0) {
18             return true;
19         }
20         return false;
21     }
22 };

哈希解法:

看起来和自己写的差不多。

 1 // 时间复杂度: O(n)
 2 // 空间复杂度:O(1)
 3 class Solution {
 4 public:
 5     bool canConstruct(string ransomNote, string magazine) {
 6         int record[26] = {0};
 7         //add
 8         if (ransomNote.size() > magazine.size()) {
 9             return false;
10         }
11         for (int i = 0; i < magazine.length(); i++) {
12             // 通过recode数据记录 magazine里各个字符出现次数
13             record[magazine[i]-'a'] ++;
14         }
15         for (int j = 0; j < ransomNote.length(); j++) {
16             // 遍历ransomNote,在record里对应的字符个数做--操作
17             record[ransomNote[j]-'a']--;
18             // 如果小于零说明ransomNote里出现的字符,magazine没有
19             if(record[ransomNote[j]-'a'] < 0) {
20                 return false;
21             }
22         }
23         return true;
24     }
25 };

*15. 三数之和

第一眼思路:

难度较大,没有思路,需着重学习

双指针法:

 代码如下:

 1 class Solution {
 2 public:
 3     vector<vector<int>> threeSum(vector<int>& nums) {
 4         vector<vector<int>> result;
 5         //对nums数组进行排序
 6         sort(nums.begin(), nums.end());
 7         for (int i = 0; i < nums.size(); i++){
 8             //第一个大于零,则不存在这样的数组
 9             if(nums[i] > 0){
10                 break;
11             }
12             //三元组第一个元素去重
13             if (i > 0 && nums[i] == nums[i - 1]){
14                 continue;
15             }
16             //定义双指针用于收缩
17             int left = i + 1;
18             int right = nums.size() - 1;
19             while (right > left){
20                 if (nums[i] + nums[left] + nums[right] > 0){
21                     right--;
22                 } else if (nums[i] + nums[left] + nums[right] < 0){
23                     left++;
24                 } else {
25                     //得到结果集
26                     result.push_back(vector<int>{nums[i], nums[left], nums[right]});
27                     while (right > left && nums[left] == nums[left + 1]) left++;
28                     while (right > left && nums[right] == nums[right - 1]) right--;
29                     //得到结果,双指针同时收缩
30                     left++;
31                     right--;
32                 }
33             }
34         }
35         return result;
36     }
37 };

 18. 四数之和

类似三数之和,利用双指针的方法,代码如下:

 1 class Solution {
 2 public:
 3     vector<vector<int>> fourSum(vector<int>& nums, int target) {
 4         vector<vector<int>> result;
 5         //对nums数组进行排序
 6         sort(nums.begin(), nums.end());
 7         for (int i = 0; i < nums.size(); i++){
 8             //剪枝处理
 9             if(nums[i] > target && nums[i] >= 0){
10                 break;
11             }
12             //i去重
13             if(i > 0 && nums[i] == nums[i - 1]){
14                 continue;
15             }
16             for (int j = i + 1; j < nums.size(); j++){
17                 //2级剪枝操作
18                 if (nums[i] + nums[j] > target && nums[i] + nums[j] >= 0) {
19                     break;
20                 }
21                 //j去重
22                 if(j > i + 1 && nums[j] == nums[j - 1]){
23                     continue;
24                 }
25                 int left = j + 1;
26                 int right = nums.size() - 1;
27                 while (right > left){
28                     if ((long)nums[i] + nums[j] + nums[left] + nums[right] < target){
29                         left++;
30                     } else if ((long)nums[i] + nums[j] + nums[left] + nums[right] > target){
31                         right--;
32                     } else {
33                         result.push_back(vector<int>{nums[i], nums[j], nums[left], nums[right]});
34                         while (right > left && nums[right] == nums[right - 1]) right--;
35                         while (right > left && nums[left] == nums[left + 1]) left++;
36                         //双指针同时收缩
37                         left++;
38                         right--;
39                     }
40                 }
41             }
42         }
43         return result;
44     }
45 };

 

标签:ransomNote,四数,15,nums,int,随想录,++,right,left
From: https://www.cnblogs.com/zsqy/p/16741982.html

相关文章

  • CF1514B AND 0, Sum Big-不学数学,你怎么会有进步呢?qaq
    Problem-1514B-Codeforces题意:给定n,k元素为[0,2^k-1],(一共2^k个数),选n个数组成数列,使得1:所有元素的&的和为02:所有元素的和尽量大解:假如n=2,k=2.可知元素只有2位0:0......
  • 1588分析和实现总纲
    1588博客总体分为两部分:协议分析和协议实现。1588协议有一定难度,主要是因为它涉及的面较广,同步算法较为复杂。(一)协议分析主要基于《IEEE1588-2008》分析1588协议中的一些重......
  • 代码随想录训练营|Day 10|459,总结,双指针
    459.RepeatedSubstringPatternGivenastring s,checkifitcanbeconstructedbytakingasubstringofitandappendingmultiplecopiesofthesubstringto......
  • 代码随想录训练营|Day 9|28
    28.FindtheIndexoftheFirstOccurrenceinaStringGiventwostrings needle and haystack,returntheindexofthefirstoccurrenceof needle in hayst......
  • 做题记录整理dp15 P1772. [ZJOI2006] 物流运输(2022/9/28)
    P3648[APIO2014]序列分割第一次做斜率优化的题题解看懂了,但没有完全看懂等以后得回来看一次#include<bits/stdc++.h>#definefor1(i,a,b)for(inti=a;i<=b;i++)......
  • 15. HTML-- 块级元素和内联元素
    1.前言HTML标签(元素)可以分为两个类别,分别是块级元素和内联元素(也叫行内元素)。2.块级元素块级元素最主要的特点是它们自己独占一行,块级元素中最具代表性的就是<div>,......
  • P2671 [NOIP2015 普及组] 求和(洛谷前缀和
    P2671[NOIP2015普及组]求和1//(x+z)*(num[x]+num[z])=2//(x1+x2)*(y1+y2)+(x1+x3)*(y1+y3)+(x2+x3)*(y2+y3)3//=x1*(y1*(n-2)+y1+y2+...+yn)4//+x2*(y2*......
  • Qt小技巧15.Pro文件的床边故事
    1引言这篇文章很简单,小结下Pro文件的那些好用但是又不常用的功能,用好了Pro文件,对开发人员来说那是大有裨益,身体倍儿棒。2说正事2.1定义一个字符串宏例如我想定义一......
  • 111-15-HBase DML(插入数据)_ev
               ......
  • vs2015使用问题收集
    vs2015使用问题收集 1 CS1617:选项“6”对/langversion无效 新建的一个asp.netwebapi项目,没填加任何代码,编译通过,但运行报“CS1617:选项“6”对/langversion无效......