LeetCode日记——【数据结构】哈希表专题
预备知识:
一.HashMap
是Map接口最常用的实现类,采用哈希算法来实现,存放键值对(Map的特性)
特点是键(key)不重复,线程不安全,效率高,允许key或value为null。
1.加入键值对:对象名称.put(key,value),若键重复,新的值对会覆盖旧的值。
2.HashMap的容量(长度):对象名称.size( )
3.返回布尔类型,验证当前HashMap中是否存在指定的key:对象名称.containsKey(key)
4.返回布尔类型,验证当前HashMap中是否存在指定的value:对象名称.containsValue(value)
5.返回一个包含所有的key的Set:对象名称.keySet( )
6.返回一个包含所有的Value的Collection:对象名称.values( )
7.返回布尔类型,验证当前HashMap是否为空:对象名称.isEmpty( )
8.清空当前HashMap:对象名称.clear( )
9.返回指定key对应的value,如果该key不存在,返回null:对象名称.get(key)
10.返回指定key对应的value,如果该key不存在,返回指定的默认内容:对象名称.getOrDefault(key,defaultValue)
11.将指定HashMap中的所有键值对复制到当前HashMap中:对象名称.putAll(指定HashMap对象名称)
二.HashSet
HashSet是Set接口最常用的一个实现类。
Set接口继承自Collection,Set接口中没有新增方法,方法和Collection保持完全一致。因此Set的方法与List完全相同。
Set容器特点:无序、不可重复。无序指Set中的元素没有索引,我们只能遍历查找。
不可重复指不允许加入重复的元素。更确切地讲,新元素如果和Set中某个元素通过equals()方法对比为true,则不能加入。甚至,Set中也只能放入一个null元素,不能多个。
常用方法:add (),clear(),contains(),isEmpty,remove(),size()
题1:两数之和( Two Sum)
LeetCode题号:1
难度:Easy
题目描述:
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
代码:
1 class Solution { 2 public int[] twoSum(int[] nums, int target) { 3 HashMap <Integer,Integer> hm = new HashMap<>(); 4 for(int i=0;i<nums.length;i++){ 5 if(hm.containsKey(target-nums[i])){ 6 return new int[]{hm.get(target-nums[i]),i}; 7 }else{ 8 hm.put(nums[i],i); 9 } 10 } 11 return null; 12 } 13 }
分析:
定义一个HashMap。依次将数组中的数(key),对应的下标(value)存入该HashMap。每次都判断当前数字是否在HashMap中存在数字,与其配对之和为target。如果是,则直接返回两数下标,若否,继续往HashMap中存放键值对,然后再判断。
题2:存在重复元素(Contains Duplicate)
LeetCode题号:217
难度:Easy
题目描述:
给定一个整数数组,判断是否存在重复元素。
如果任意一值在数组中出现至少两次,函数返回 true
。如果数组中每个元素都不相同,则返回 false
。
1 class Solution { 2 public boolean containsDuplicate(int[] nums) { 3 Set <Integer> set = new HashSet<>(); 4 for(int num:nums){ 5 set.add(num); 6 } 7 return nums.length>set.size(); 8 } 9 }
分析:
利用HashSet中元素不可重复的特点,将nums数组中的元素一个个存入HashSet。如果有重复的,HashSet会自动覆盖。最后比较HashSet的长度与数组长度,就可以判断是否有重复数字。
题3:最长和谐序列
LeetCode题号:217
难度:Easy
题目描述:
和谐数组是指一个数组里元素的最大值和最小值之间的差别正好是1。
现在,给定一个整数数组,你需要在所有可能的子序列中找到最长的和谐子序列的长度。
示例 :
输入: [1,3,2,2,5,2,3,7]
输出: 5
原因: 最长的和谐数组是:[3,2,2,2,3].
代码:
1 class Solution { 2 public int findLHS(int[] nums) { 3 HashMap <Integer,Integer> count = new HashMap<>(); 4 for(int num:nums){ 5 count.put(num,count.getOrDefault(num,0)+1); 6 } 7 int longest=0; 8 for(int num:count.keySet()){ 9 if(count.containsKey(num+1)){ 10 longest=Math.max(longest,count.get(num+1)+count.get(num)); 11 } 12 } 13 return longest; 14 } 15 }
分析:
首先创建一个HashMap,其中存放nums中存在的数字(key)以及它的计数值(value)。
然后我们对这个HashMap中所有的key进行遍历。如果判断到HashMap中存在比当前的key大1的key,则定义一个变量longest计算key对应的value(计数值)与key+1对应的value(计数值)之和,不断更新,最终得到最大的longest。
题4:最长和谐序列
LeetCode题号:128
难度:Hard
题目描述:
给定一个未排序的整数数组,找出最长连续序列的长度。
要求算法的时间复杂度为 O(n)。
示例:
输入: [100, 4, 200, 1, 3, 2]
输出: 4
解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。
代码:
1 class Solution { 2 public int longestConsecutive(int[] nums) { 3 Set<Integer> num_set = new HashSet<Integer>(); 4 for (int num : nums) { 5 num_set.add(num); 6 } 7 int longestStreak = 0; 8 for (int num : num_set) { 9 if (!num_set.contains(num-1)) { 10 int currentNum = num; 11 int currentStreak = 1; 12 while (num_set.contains(currentNum+1)) { 13 currentNum += 1; 14 currentStreak += 1; 15 } 16 longestStreak = Math.max(longestStreak, currentStreak); 17 } 18 } 19 return longestStreak; 20 } 21 }
分析:
我写了一遍,并不能输出最大长度...有谁能看懂这个代码吗...
哈希表专题完结撒花~