We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
本文为博主算法学习过程中的学习笔记,主要内容来源于其他平台或书籍,出处请参考下方 参考&感谢 一节。
哈希映射 是用于存储 (key, value) 键值对的一种实现。
(key, value)
使用哈希映射的第一个场景是,我们 需要更多的信息,而不仅仅是键。然后通过哈希映射 建立密钥与信息之间的映射关系。
另一个常见的场景是 按键聚合所有信息。我们也可以使用哈希映射来实现这一目标。
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
HashMap入门的经典题。
HashMap
简单的方式是使用双层循环进行暴力破解,这种算法时间复杂度为O(N^2)。
O(N^2)
而使用HashMap则可以将问题在一层循环中进行解决,时间复杂度仅O(N):
O(N)
class Solution { public int[] twoSum(int[] nums, int target) { HashMap<Integer, Integer> map = new HashMap<>(); int[] result = new int[2]; for (int i = 0; i < nums.length; i++) { int value = nums[i]; int find = target - value; if (map.containsKey(find) && map.get(find) != i) { result[0] = i; result[1] = map.get(find); break; } map.put(nums[i], i); } return result; } }
给定两个字符串 s 和 t,判断它们是否是同构的。
如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。
所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。
你可以假设 s 和 t 具有相同的长度。
输入: s = "egg", t = "add" 输出: true 输入: s = "foo", t = "bar" 输出: false
通过2个HashMap存储各自字符对应最初的索引,然后进行比较,当字符对应的最初索引不同时,说明2个字符串不是同构的:
class Solution { public boolean isIsomorphic(String s, String t) { char[] char1 = s.toCharArray(); char[] char2 = t.toCharArray(); HashMap<Character, Integer> map1 = new HashMap<>(); HashMap<Character, Integer> map2 = new HashMap<>(); for (int i = 0; i < char1.length; i++) { char c1 = char1[i]; char c2 = char2[i]; if (!map1.containsKey(c1)) map1.put(c1, i); if (!map2.containsKey(c2)) map2.put(c2, i); if (map1.get(c1) != map2.get(c2)) return false; } return true; } }
https://leetcode-cn.com/problems/minimum-index-sum-of-two-lists/
这道题的难点是发现映射关系,即 最爱餐厅 -> 索引值 的映射关系。
通过遍历将该映射关系存储到HashMap中后,再次通过一次遍历找出索引值和最小的餐厅,因为索引值最小的情况可能不止一个,因此用一个List进行维护,最终将答案遍历输出:
List
class Solution { public String[] findRestaurant(String[] list1, String[] list2) { HashMap<String, Integer> map = new HashMap<>(); List<Integer> posList = new ArrayList<>(); int minPosNum = Integer.MAX_VALUE; for (int i = 0; i < list1.length; i++) { map.put(list1[i], i); } for (int i = 0; i < list2.length; i++) { String favorite = list2[i]; Integer position = map.get(favorite); if (position != null) { int posNum = i + position; if (minPosNum > posNum) { minPosNum = posNum; posList.clear(); posList.add(i); } else if (minPosNum == posNum) { posList.add(i); } } } String[] result = new String[posList.size()]; for (int i = 0; i < posList.size(); i++) result[i] = list2[posList.get(i)]; return result; } }
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
示例:
s = "leetcode" 返回 0. s = "loveleetcode" 返回 2.
您可以假定该字符串只包含小写字母。
比较简单,通过2次遍历,第一次遍历将每个字符对应出现的次数进行存储,第二次遍历每个字符的出现次数,当出现次数为1,返回该字符的索引即可。
1
class Solution { public int firstUniqChar(String s) { char[] arr = s.toCharArray(); HashMap<Character, Integer> map = new HashMap<>(); // 遍历将所有字符的频率输出到Map中 for (int i = 0; i < arr.length; i++) { char c = arr[i]; if (map.containsKey(c)) { map.put(c, map.get(c) + 1); } else { map.put(c, 1); } } for (int i = 0; i < arr.length; i++) { char c = arr[i]; if (map.get(c) == 1) return i; } return -1; } }
给定两个数组,编写一个函数来计算它们的交集。
输入: nums1 = [1,2,2,1], nums2 = [2,2] 输出: [2,2] 输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4] 输出: [4,9]
输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。 我们可以不考虑输出结果的顺序。
仍然是通过2次遍历,第一次遍历将nums1[]每个数字对应出现的次数进行存储,第二次遍历nums2[],然后和之前的结果进行匹配,最终返回结果。
nums1[]
nums2[]
class Solution { public int[] intersect(int[] nums1, int[] nums2) { HashMap<Integer, Integer> map = new HashMap<>(); // 遍历数组将所有元素和其数量存入map中 for (int i = 0; i < nums1.length; i++) { int key = nums1[i]; if (map.containsKey(key)) { map.put(key, map.get(key) + 1); } else { map.put(key, 1); } } int[] result = new int[nums2.length]; int pos = 0; for (int i = 0; i < nums2.length; i++) { int key = nums2[i]; if (map.containsKey(key) && map.get(key) >= 1) { result[pos] = key; pos++; map.put(key, map.get(key) - 1); } } return Arrays.copyOf(result, pos); } }
给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值最大为 k。
nums [i] = nums [j]
输入: nums = [1,2,3,1], k = 3 输出: true 输入: nums = [1,0,1,1], k = 1 输出: true 输入: nums = [1,2,3,1,2,3], k = 2 输出: false
题目理解了就好做了,关键是数组内相同的数字最小距离是否不大于k,做一次遍历,每次都将数字作为key,其索引作为value进行存储。
k
key
value
遍历结束前,只要有一个满足要求就可以返回true,否则最终返回false即可。
true
false
class Solution { public boolean containsNearbyDuplicate(int[] nums, int k) { HashMap<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) { int key = nums[i]; if (map.containsKey(key)) { int oldPos = map.get(key); if (i - oldPos <= k) { return true; } else { map.put(key, i); } } else { map.put(key, i); } } return false; } }
文章绝大部分内容节选自LeetCode,概述:
LeetCode
例题:
Hello,我是 却把清梅嗅 ,如果您觉得文章对您有价值,欢迎 ❤️,也欢迎关注我的 博客 或者 GitHub。
如果您觉得文章还差了那么点东西,也请通过关注督促我写出更好的文章——万一哪天我进步了呢?
The text was updated successfully, but these errors were encountered:
No branches or pull requests
哈希映射用法及算法例题
用法
哈希映射 是用于存储
(key, value)
键值对的一种实现。使用哈希映射的第一个场景是,我们 需要更多的信息,而不仅仅是键。然后通过哈希映射 建立密钥与信息之间的映射关系。
另一个常见的场景是 按键聚合所有信息。我们也可以使用哈希映射来实现这一目标。
例题
1、两数之和
题目描述
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
解题思路及实现
HashMap
入门的经典题。简单的方式是使用双层循环进行暴力破解,这种算法时间复杂度为
O(N^2)
。而使用
HashMap
则可以将问题在一层循环中进行解决,时间复杂度仅O(N)
:2、同构字符串
题目描述
给定两个字符串 s 和 t,判断它们是否是同构的。
如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。
所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。
你可以假设 s 和 t 具有相同的长度。
示例:
解题思路及实现
通过2个
HashMap
存储各自字符对应最初的索引,然后进行比较,当字符对应的最初索引不同时,说明2个字符串不是同构的:3、两个列表的最小索引总和
题目描述
https://leetcode-cn.com/problems/minimum-index-sum-of-two-lists/
解题思路及实现
这道题的难点是发现映射关系,即 最爱餐厅 -> 索引值 的映射关系。
通过遍历将该映射关系存储到
HashMap
中后,再次通过一次遍历找出索引值和最小的餐厅,因为索引值最小的情况可能不止一个,因此用一个List
进行维护,最终将答案遍历输出:4、字符串中的第一个唯一字符
题目描述
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
示例:
您可以假定该字符串只包含小写字母。
解题思路及实现
比较简单,通过2次遍历,第一次遍历将每个字符对应出现的次数进行存储,第二次遍历每个字符的出现次数,当出现次数为
1
,返回该字符的索引即可。5、两个数组的交集 II
题目描述
给定两个数组,编写一个函数来计算它们的交集。
输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
我们可以不考虑输出结果的顺序。
解题思路及实现
仍然是通过2次遍历,第一次遍历将
nums1[]
每个数字对应出现的次数进行存储,第二次遍历nums2[]
,然后和之前的结果进行匹配,最终返回结果。6、存在重复元素 II
题目描述
给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得
nums [i] = nums [j]
,并且 i 和 j 的差的绝对值最大为 k。解题思路及实现
题目理解了就好做了,关键是数组内相同的数字最小距离是否不大于
k
,做一次遍历,每次都将数字作为key
,其索引作为value
进行存储。遍历结束前,只要有一个满足要求就可以返回
true
,否则最终返回false
即可。参考 & 感谢
文章绝大部分内容节选自
LeetCode
,概述:例题:
关于我
Hello,我是 却把清梅嗅 ,如果您觉得文章对您有价值,欢迎 ❤️,也欢迎关注我的 博客 或者 GitHub。
如果您觉得文章还差了那么点东西,也请通过关注督促我写出更好的文章——万一哪天我进步了呢?
The text was updated successfully, but these errors were encountered: