哈希表部分:242.有效的字母异位词, 349. 两个数组的交集, 202. 快乐数, 1. 两数之和

代码随想录算法训练营第4天 | 哈希表部分:242.有效的字母异位词, 349. 两个数组的交集, 202. 快乐数, 1. 两数之和

哈希表部分

使用O(1)的时间复杂度定位到元素,根据hash函数和冲突解决方法将一组关键字映射到一组有限的地址空间
哈希冲突:不同的关键字经过哈希函数的计算之后得到的地址相同,产生冲突
哈希冲突的解决方法:
线性探测法:从发生冲突的位置开始,依次判断下一个单元是否是空的,如果空则插入,否则继续判断下一个单元
平方探测法:在发生冲突的位置依次加上12 ,22,直到找到空闲的位置
双重散列探测:前一个函数使用取余法取得散列地址,后一个同样,只不过后面的作为探查序列的增量
伪随机探查:建立一个伪随机函数作为探查序列

242. 有效的字母异位词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词

思路:将数据作为k,数据出现的次数作为v保存在Hashmap中,分别对字符串s和进行遍历,最后遍历k的同时进行比较

   public boolean isAnagram(String s, String t) {
         Map<Character,Integer> map1=new HashMap<>();
         Map<Character,Integer> map2=new HashMap<>();
         if(s.length()!=t.length()){
             return false;
         }
         for(int i=0;i<s.length();i++){
             if(map1.containsKey(s.charAt(i))){
                 map1.put(s.charAt(i),map1.get(s.charAt(i))+1);
             }else{
                map1.put(s.charAt(i),1);
             }
             if(map2.containsKey(t.charAt(i))){
                 map2.put(t.charAt(i),map2.get(t.charAt(i))+1);
             }else{
                 map2.put(t.charAt(i),1);
             }
         }
        
         for(int i=0;i<t.length();i++){
            /* int x=map1.get(t.charAt(i));
             int y=map2.get(t.charAt(i));
             if(x!=y){
                 return false;
             }*/
             if(map1.get(t.charAt(i))==null){
                 return false;
             }
             //补充:== b.equals(a)的使用区间
             if(!map1.get(t.charAt(i)).equals(map2.get(t.charAt(i)))){
                 return false;
             }
         }
         return true;

    }

补充:== equals的区别
本道题目中是map中get方法的返回值类型是value的类型(Interger)
Integer在-128-127之间可以使用==比较,不在这个范围的值都需要equals进行比较

349. 两个数组的交集

给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

思路:将数据保存为key,数据出现的次数保存为value,对nums1遍历时加1,对nums2遍历时-1,最终判断key对应的value值是否为0。
这样想的思路存在问题:如果nums1中有2个4,nums2中只有一个4,事实上,两者是存在交集的,但是根据上面的判断,value此时不为0;
思路改进:
首先对数据进行去重,这样就能保证交集中key对应的value的值为0(看答案)
思路是对的,使用将数据保存在HashSet中
??这边本来想着是不是map中的key的对应的默认值为0?map中有没有默认值

补充:hashmap中默认的部分时装填因子0.75,容量大小是16,并没有我认为的一个默认的键值对,只有在key存在的情况下,如果没给value赋值的话,会设置为一个默认值
补充:如何将set集合转换为int[ ]数组(老大难问题)
调用set1.toArray()函数仅仅转换为Integer[ ]集合
方法1:使用迭代器遍历,将集合中的每一个Integer转换为int (a.intValue())
方法2:resSet.stream().mapToInt(x -> x).toArray();

 public int[] intersection(int[] nums1, int[] nums2) {
          Set<Integer> set1=new HashSet<>();
           Set<Integer> resSet=new HashSet<>();
          int len=Math.min(nums1.length,nums2.length);
          //int[] res=new int[len];
          for(int i=0;i<nums1.length;i++){
              if(!set1.contains(nums1[i])){
                  set1.add(nums1[i]);
              }
          }
          //遍历数组2的过程中,判断该元素在数组1中是否出现过,出现过的话再加入结果集中,结果集也是一个HashSet类型的集合
          for(int j=0;j<nums2.length;j++){
              if(set1.contains(nums2[j])){
                  resSet.add(nums2[j]);
              }
          }
          return  resSet.stream().mapToInt(x -> x).toArray();
          //写代码中遇到的思路:直接遍历数组2,最后进行一个遍历对set1,set1的结果进行整合,遇到了问题
          //如果再进行一遍遍历的话,感觉无论使用哪一个数组的长度都不对

202. 快乐数

编写一个算法来判断一个数 n 是不是快乐数。「快乐数」 定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果这个过程 结果为 1,那么这个数就是快乐数。如果 n 是 快乐数 就返回 true ;不是,则返回 false

思路:就是按照题目给的公式不断地判断循环,然后去判断,但是这样写的话,遇到不是快乐数的n,循环不会停止
在这里插入图片描述
答案:
将每个位置上的平方和sum保存在set中,这样就不需要再重复运算,查找的时间复杂度O(1)

public boolean isHappy(int n) {
      Set<Integer> set1=new HashSet<>();
      //主要是对重复元素的去除
      //while(n>1 && !set1.contains(n))也可以
      while(n!=1 && !set1.contains(n)){//更准确的表达题目的要求
          int sums=0;
          set1.add(n);
          while(n>0){//注意
              sums +=(n%10)*(n%10);
              n =n/10;
          }
          n=sums;
      }
      return n==1;
    }

1. 两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案

思路:暴力法O(n2)
思路2:map实现,一次遍历,如果target-当前位置处的数组元素在map中出现,立刻结束

 public int[] twoSum(int[] nums, int target) {
      Map<Integer,Integer> map=new HashMap<>();
      int[] res=new int[2];
      for(int i=0;i<nums.length;i++){
          if(map.containsKey(target-nums[i])){
              res[0]=i;
              res[1]=map.get(target-nums[i]).intValue();//转换
          }else{
              map.put(nums[i],i);
          }
      }
      return res;
    }

总结:
HashSet
==和equals的区别
集合转换成int[]数组

`

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值