算法训练-Day5|242.有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和

        当我们需要快速判断一个元素是否出现在集合里,或者说一个元素是否出现过,则可以使用哈希法。

        哈希法是一种以空间换时间的方法。

242.有效的字母异位词

        数组其实就是一个简单哈希表,而且这道题目中字符串只有小写字符,那么就可以定义一个数组,来记录字符串s里字符出现的次数。对t中出现的字符映射哈希表索引上的数值再做-1的操作。最后看下record数组中元素是否全为0。若全为0,说明s和t是字符异位词,若不全0,则s和t不是字符异位词。

        如果要用数组来做哈希的题目,则题目中需要限制数值的大小。而且如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。

 public boolean isAnagram(String s, String t) {
        //字典解法    时间复杂度O(m+n)
        int [] record = new int[26];  //使用哈希法,创建数组来存储元素

        for(int i = 0;i < s.length();i++)
            record[s.charAt(i)-'a']++;  // 并不需要记住字符a的ASCII,只要求出一个相对数值就可以了

        for(int j = 0;j < t.length();j++)
            record[t.charAt(j)-'a']--;

        for(int k = 0;k < 26;k++)
            if(record[k] != 0)    //若record数组存在不为0的元素,说明s和t每个字符出现的次数不相同
                return false;

        return true;  //record数组中所有元素的值为0,说明s和t为字母异位词
    }

349. 两个数组的交集

public int[] intersection(int[] nums1, int[] nums2) {
        //由题意可得,元素不可重复且可以无序,因此用unordered_set结构
        if(nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0)
            return new int [0];

        Set<Integer> set1 = new HashSet<Integer>();
        Set<Integer> resultSet = new HashSet<Integer>();

        //遍历num1数组,将元素放入集合中
        for(int i:nums1)
            set1.add(i);

        //遍历nums2数组,判断哈希表中是否存在该元素
        for(int i:nums2)
            if(set1.contains(i))
                resultSet.add(i);
        
        //转换成数组:另一个创建一个数组存放交集中的元素,最后返回数组
        int [] arr = new int[resultSet.size()];
        int j = 0;
        for(int i:resultSet)
            arr[j++] = i;

        return arr;
    }

202. 快乐数

根据观察,会有以下三种可能。

  1. 最终会得到 111。
  2. 最终会进入循环。
  3. 值会越来越大,最后接近无穷大。

但是第三种可能不会出现,因为假设这个数很大,但是在求各个位数的平方和后该数会变小,4位或4位以上的数字在每一步都会丢失一位,直到降到3位为止,所以不会发生无穷大的情况。

    public boolean isHappy(int n) {
        //创建集合record,判断某一元素是否出现过
        Set<Integer> record = new HashSet<>();

        //若n为1,表明是快乐数;若集合中存在n,表明出现了无限循环
        while(n != 1 && !record.contains(n)){
            record.add(n);
            n = getNextNumber(n);
        }

        if(n == 1)
            return true;  //最终变为1,表明为快乐数
        else
            return false;   //n不为1,说明是无限循环,始终变不到1
    }

    //计算每个位置上的数字平方和,将该数替换掉
    public int getNextNumber(int n){
        int res = 0;
        while(n > 0){
            int temp = n%10;
            res += temp * temp;
            n = n/10;
        }
        return res;
    }

1. 两数之和

        在本题中,要掌握的函数是containsKey(Object key)get()以及put()函数。

        如何判断一个Map中是否包含某个键值对呢?Java中提供了一个方法containsKey,用于判断Map中是否包含指定的键。

        get方法是Map接口中用于获取键所映射的值的方法,get(Object key)。

        在Java中,我们通常会使用Map作为数据结构来存储一些键值对。而其中最常用的方法就是put()方法,它可以用来往Map中添加一个键值对。map.put("key1", "value1")

  //因为需要查找值key及其下标value,因此用map
    public int[] twoSum(int[] nums, int target) {
        int [] res = new int [2];  //存放返回的下标值

        Map<Integer,Integer> map = new HashMap<>();  //因为map有key和value,可以用来存放元素值及其下标索引
        for(int i = 0;i < nums.length;i++){
            int temp = target - nums[i];
            if(map.containsKey(temp)){  //说明map中有元素值与nums[i]相加后为target
                res[0] = i;
                res[1] = map.get(temp); //得到key为temp的value值
            }
            map.put(nums[i],i);  //若剩下的元素值不在map中,则将nums[i]加入map中
        }
        return res;
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值