首页 > 其他分享 >day7 | 哈希表(2)

day7 | 哈希表(2)

时间:2023-11-18 21:00:45浏览次数:29  
标签:map right nums int day7 ++ 哈希 left

题目链接:454. 四数相加 II - 力扣(LeetCode)

题目描述:

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

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

解题思路:参考代码随想录 (programmercarl.com)

 1 class Solution {
 2     public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
 3         int res = 0;
 4         Map<Integer,Integer> map = new HashMap<Integer, Integer>(); //创建一个map
 5         for (int i : nums1){
 6             for (int j : nums2){
 7                 int sum = i + j;
 8                 map.put(sum, map.getOrDefault(sum, 0) + 1);
 9             }
10         }
11         for(int i : nums3){
12             for (int j : nums4){
13                 res += map.getOrDefault(0-i-j, 0);
14             }
15         }
16         return res;
17     }
18 }
  • 在java语言中的Map操作:

  Map初始化:

Map<String, String>map = new HashMap<String, String>();

  插入元素:

map.put("key1", "value1");

  获取元素:

map.get("key1");

  移除元素:

map.remove("key1");

  清空map:

map.clear();
  • hashmap.getOrDefault(Object key, V defaultValue)函数的用法:

  参数说明:key - 键、defaultValue - 当指定的key并不存在映射关系中,则返回的默认值。

  在题目中使用defaultValue函数对map进行插入,在遍历的过程中a+b的值出现了重复,直接将value值+1,节约了一些时间。

 

题目链接:383. 赎金信 - 力扣(LeetCode)

题目描述:

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

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

magazine 中的每个字符只能在 ransomNote 中使用一次。

解题思路:

  这是一个很典型的 字符串a 能否组成 字符串b 的问题——数组在哈希法中的应用。

  解题一般分为4步:

  1. 定义一个哈希映射的数组record[ ]

  2. 遍历 字符串a中出现的字符,并对出现的次数进行计数;

  3. 遍历 字符串b中出现的字符,计算 b中出现的字符数-a中出现的字符数

  4. 判断 record数组中是否出现负数即b-a<0(也就是说字符串b不能由字符串a所构成)

 1 class Solution {
 2     public boolean canConstruct(String ransomNote, String magazine) {
 3         if (ransomNote.length() > magazine.length()){
 4             return false;
 5             //如果ransomNote这个字符串比magazine这个字符串还要长,那magazine必不可能有ransomNote所构成
 6         }
 7         int[] record = new int[26];
 8         for(char c : magazine.toCharArray()){
 9             record[c - 'a'] += 1;
10         }
11         for(char c : ransomNote.toCharArray()){
12             record[c - 'a'] -= 1;
13         }
14         for(int i : record){
15             if(i < 0){
16                 return false;
17             }
18         }
19         return true;
20     }
21 }

toCharArray()方法,将字符串转换为字符数组。

 

题目链接:15. 三数之和 - 力扣(LeetCode)

题目描述:

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

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

解题思路:

  因为题目中强调 答案中不可以包含重复的三元组 ,所以要对三元组中的每一个元素进行去重的操作,使用哈希法难以实现,所以采用双指针法。

  双指针法:定义一个left指针和right指针。

    1. 定义双指针,并将数组从小到大进行排序

    2. 根据三数之和对指针进行移动(三数和 > 0, 数偏大,调小,right--;三数和 < 0,数偏小,调大,left++)在这个过程中要对三个元素进行去重的操作。

  注意:

    对i进行去重:使用的判断条件是nums[i] == nums[i-1]而不是使用nums[i] == nums[i+1],要注意甄别两者的区别。前者是判断i是否有重复,后者是判断三元组中的i是否和left指针所指向的元素有重复。

    对left和right去重:在对left和right所对应的元素进行去重的时候,要在收获三元组这个结果之后进行去重,如果从whlie(right>left)这个循环一开始就进行去重的操作,会造成结果的缺失。

 1 class Solution {
 2     public List<List<Integer>> threeSum(int[] nums) {
 3         List<List<Integer>> result = new ArrayList<>();
 4         Arrays.sort(nums);
 5         for(int i = 0; i < nums.length; i++){
 6             //排序之后如果第一个元素已经大于零,那么无论如何组合都不可能凑成三元组,直接返回结果即可。
 7             if(nums[i] > 0){return result;}
 8             //对a去重
 9             if(i > 0 && nums[i]==nums[i-1]){continue;}
10             int left = i + 1;
11             int right = nums.length-1;
12             while(right > left){
13                 int sum = nums[i] + nums[left] + nums[right];
14                 if(sum > 0){
15                     right--;
16                 }
17                 else if(sum < 0){
18                     left++;
19                 }
20                 else{
21                     result.add(Arrays.asList(nums[i],nums[left],nums[right]));
22                 
23                 while(right > left && nums[right]==nums[right-1])right--;
24                 while(right > left && nums[left]==nums[left+1])left++;
25 
26                 right--;
27                 left++;
28             }
29         }
30     }
31     return result;
32     }
33 }

存疑:这个语句不是很懂,还有一些array方法的应用

 List<List<Integer>> result = new ArrayList<>();

 

题目链接:18. 四数之和 - 力扣(LeetCode)

题目描述:

解题思路:代码随想录 (programmercarl.com)

 

 1 class Solution {
 2 public:
 3     vector<vector<int>> fourSum(vector<int>& nums, int target) {
 4         vector<vector<int>> result;
 5         sort(nums.begin(), nums.end());
 6         for (int k = 0; k < nums.size(); k++) {
 7             // 剪枝处理
 8             if (nums[k] > target && nums[k] >= 0) {
 9                 break; // 这里使用break,统一通过最后的return返回
10             }
11             // 对nums[k]去重
12             if (k > 0 && nums[k] == nums[k - 1]) {
13                 continue;
14             }
15             for (int i = k + 1; i < nums.size(); i++) {
16                 // 2级剪枝处理
17                 if (nums[k] + nums[i] > target && nums[k] + nums[i] >= 0) {
18                     break;
19                 }
20 
21                 // 对nums[i]去重
22                 if (i > k + 1 && nums[i] == nums[i - 1]) {
23                     continue;
24                 }
25                 int left = i + 1;
26                 int right = nums.size() - 1;
27                 while (right > left) {
28                     // nums[k] + nums[i] + nums[left] + nums[right] > target 会溢出
29                     if ((long) nums[k] + nums[i] + nums[left] + nums[right] > target) {
30                         right--;
31                     // nums[k] + nums[i] + nums[left] + nums[right] < target 会溢出
32                     } else if ((long) nums[k] + nums[i] + nums[left] + nums[right]  < target) {
33                         left++;
34                     } else {
35                         result.push_back(vector<int>{nums[k], nums[i], nums[left], nums[right]});
36                         // 对nums[left]和nums[right]去重
37                         while (right > left && nums[right] == nums[right - 1]) right--;
38                         while (right > left && nums[left] == nums[left + 1]) left++;
39 
40                         // 找到答案时,双指针同时收缩
41                         right--;
42                         left++;
43                     }
44                 }
45 
46             }
47         }
48         return result;
49     }
50 };

 

  

 

标签:map,right,nums,int,day7,++,哈希,left
From: https://www.cnblogs.com/inbreak/p/17723735.html

相关文章

  • A组Day7
    A.放置石子我们设第一格的东西为\(x\),则接下来的格数为\[2:1+x\\3:2x+1\\4:3x+2\\5:5x+3\\...\]易得x的系数就是原来的斐波那契额数列,而后面加上来的也是!我们可以打表左边为系数表,右边为加的数表#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;l......
  • 代码随想录算法训练营第六天 |● 哈希表理论基础 ● 242.有效的字母异位词 ● 349.
    今日学习的文章链接和视频链接https://programmercarl.com/哈希表理论基础.html242.有效的字母异位词varisAnagram=function(s,t){if(s.length!==t.length)returnfalseletmap=newMap();for(letcharofs){if(!map.get(char)){......
  • 字符串哈希算法
    一、字符串哈希:将一串字符串映射成一个整数,并用它来代替字符串进行比较。这样俩个字符串的比较就变成俩个整数的比较,可以将时间复杂度减少至O(1)二、哈希函数:为了将字符串转化为整数,需要一个哈希函数hash,使得以下条件成立:如果字符串s==t那么hash(s)==hash(t)。一般情况下采......
  • 第六章 消息认证和哈希函数 —— 现代密码学(杨波)课后题答案解析
    第五章作业参考答案1.6.1.3节的数据认证算法是由CBC模式的DES定义的,其中初始向量取为0,试说明使用CFB模式也可获得相同的结果。解:设需认证的数据分为64比特长的分组,D1,D2,…,DN,其中DN不够64比特则右边补0,由题设,数据认证算法相当于在CBC模式中初始向量取为0,并按如下关系进行:   ......
  • 算法刷题记录-哈希表
    算法刷题记录-哈希表有效的字母异位词给定两个字符串*s*和*t*,编写一个函数来判断*t*是否是*s*的字母异位词。注意:若*s*和*t*中每个字符出现的次数都相同,则称*s*和*t*互为字母异位词。示例1:输入:s="anagram",t="nagaram"输出:true示例2:输入:s......
  • 【golang】Golang 哈希码 hashcode 输入一个字符串,得到一个唯一标识码
    如何输入一个字符串,得到一个唯一的hashcode?例子如下:packagemainimport("fmt""hash/crc32")//Stringhashesastringtoauniquehashcode.////crc32returnsauint32,butforouruseweneed//andnonnegativeinteger.Herewec......
  • 根据数字值和探究 哈希以及unordered_map实现
    leecode里面的第一题,是两数值和,内容如下/**************************************************************给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。......
  • 字符串哈希
    方法通常采用多项式Hash的方法,也就是说将字符串看做一个b进制的数。进制数选择(大于所有字符对应的数字的最大值,且为质数),如:1312331333119260817等。模数选择(双\(10^9\)的模数或者直接自然溢出):1926081719660813等。然后就可以愉快的哈希了!code(自然溢出)ullhashh(s......
  • 2023-11-11:用go语言,字符串哈希+二分的例题。 给定长为 n 的源串 s,以及长度为 m 的模式
    2023-11-11:用go语言,字符串哈希+二分的例题。给定长为n的源串s,以及长度为m的模式串p,要求查找源串中有多少子串与模式串匹配,s'与s匹配,当且仅当s'与s长度相同,且最多有k个位置字符不同。其中1<=n,m<=10^6,0<=k<=5。来自左程云。答案2023-11-11:go代码用灵捷3.5......
  • 2023-11-11:用go语言,字符串哈希+二分的例题。 给定长为 n 的源串 s,以及长度为 m 的模式
    2023-11-11:用go语言,字符串哈希+二分的例题。给定长为n的源串s,以及长度为m的模式串p,要求查找源串中有多少子串与模式串匹配,s'与s匹配,当且仅当s'与s长度相同,且最多有k个位置字符不同。其中1<=n,m<=10^6,0<=k<=5。来自左程云。答案2023-11-11:go代码用......