【Leecode】代码随想录哈希篇day5(在“有元素再次出现时”实现哈希(数组&HashSet&HashMap))

java实现hash表基本操作

HashMap散列表基本操作

//创建hash
//(创建时key-value的数据类型可不同)
HashMap<instanceof(key), instanceof(value)> hashmap = new HashMap<instanceof(key), instanceof(value)>();
/*创建Hashmap<Integer, String> hashmap = new Hashmap<int,String>();为例子按索引增删改查*/

//增
hashmap.put(1, "str1");
hashmap.put(2, "str2");
/*执行后表内为{1="str1", 2="str2"}*/

//删
hashmap.remove(2);//删某key对应value
/*执行后表内为{1="str1"}*/
hashmap.clear();//清空所有键值对

//改(替换指定key的value)
hashmap.replace(1, "string1");
/*返回0*/

//查
hashmap.isEmpty();//判空
hashmap.get(1);
hashmap.size();
/*返回表中键值对个数1*/
hashmap.getOrDefault(key, defaultValue);
/*表中有值返回值,没有值则使用默认值defaultValue*/
hashmap.values();
/*返回{"string1"},所有key对应的value组成表*/

//forech遍历表中每一个键值对组成的对象entry
for(var entry : hashmap.entrySet())
{
	int key = entry.getKey();
	int val = entry.getValue();
}

HashSet集合基本操作

//创建hashset
Set<Integer> hashset= new HashSet<Integer>();
//增
hashset.add(1);
//查
hashset.contains(1);
//删
hashset.remove(1);
hashset.clear();//删除所有元素

数组实现hash表

class Solution {
    public boolean isAnagram(String s, String t) {
        if(s.length() != t.length()) return false;
        char cnt[] = new char[26];
        for(int i = 0; i < s.length(); i++)
        {
            int idx = s.charAt(i) - 'a';
            cnt[idx]++;
        }
        for(int i = 0; i < t.length(); i++)
        {
            int idx = t.charAt(i) - 'a';
            cnt[idx]--;
            if(cnt[idx] < 0) return false;
        }
        for(int i = 0; i < 26; i++) 
        {
            if(cnt[i] > 0) return false;
        }
        return true;
    }
}

java字符串不能像c++一样直接遍历,用toCharArray()后foreach和charAt(index)方可实现遍历。

  • 复杂度:时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( 1 ) O(1) O(1)

HashSet实现哈希表

  • 题目链接:两数组不重复的相同元素
  • 我的解法:由于数组中正整数范围的限制,使用一个数组记录+hashset存储两数组相同元素的方法记录,本质还是使用数组实现的hash表
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        int[] cnt1 = new int[1001];
        HashSet<Integer> ans = new HashSet<Integer>();
        for(int i = 0; i < nums1.length; i++) cnt1[nums1[i]]++;//构建hash表
        for(int i = 0; i < nums2.length; i++)
        {
            if(cnt1[nums2[i]] > 0) ans.add(nums2[i]);
        }
        int size = ans.size();
        int answer[] = new int[size];
        int idx = 0;
        for(int num : ans) answer[idx++] = num;
        return answer;
    }
}
  • 复杂度:时间复杂度 O ( n + m ) O(n + m) O(n+m),对应遍历原来两数组和将hashmap转换成数组形式输出的复杂度。
  • 拓展解法:当数组中存储的数字对应的取值范围没有被给出时,使用set构建hash表可避免空间浪费
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
    	//判断是否需要寻找
        if (nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0) {
            return new int[0];
        }
        Set<Integer> set = new HashSet<>();
        Set<Integer> res = new HashSet<>();
        //遍历数组1
        for (int i : nums1) {
            set.add(i);
        }
        //遍历数组2的过程中判断哈希表中是否存在该元素
        for (int i : nums2) {
            if (set.contains(i)) {
                res.add(i);
            }
        }
        //set转化为数组的另一种方法
        return res.stream().mapToInt(x -> x).toArray();
     }
}
  • 题目链接:快乐数果然快乐
  • 最终解法:用set充当hash表,这里审题(无限循环==重新计算出来的n会再次出现)
class Solution {
   public boolean isHappy(int n) {
       Set<Integer> hashset = new HashSet<Integer>();
       while((n != 1) && (!hashset.contains(n)))
       {
           hashset.add(n);
           n = cntHappyNum(n);
       }
       if(n == 1) return true;
       return false;
   }

   public int cntHappyNum(int ans){
       int sum = 0;
       while(ans > 0)
       {
           sum += (ans % 10) * (ans % 10);
           ans = ans / 10;
       }
       return sum;
   }
}
  • 复杂度:时间复杂度 O ( l o g n ) O(logn) O(logn),空间复杂度 O ( l o g n ) O(logn) O(logn),是cntHappyNum函数带来的复杂度

HashMap实现哈希表

  • 题目链接:
  • 我的解法:用哈希表同时记录数字和下标,单向遍历找当前num和为target的搭子有则返回,没则加入当前num进表
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int ans[] = new int[2];
        HashMap<Integer,Integer> hashmap = new HashMap<Integer, Integer>();
        for(int i = 0; i < nums.length; i++)
        {
            int num = nums[i];
            if(hashmap.containsKey(target - num))
            {
                ans[0] = hashmap.get(target-num);
                ans[1] = i;
            }
            else hashmap.put(num, i);
        }
        return ans;
    }
}

看题解还可以两个指针相向而行双管齐下,执行速度会快很多

  • 复杂度:时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( n ) O(n) O(n)
  • 12
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值