代码随想录第六天

内容:

  1. 有效的字母异位词(242)
  2. 两个数组的交集(349)
  3. 快乐数(202)
  4. 两数之和(1)

1.有效的字母异位词

难度:🔥🔥

1.1 思路分析

最先出现在我的脑海中的思路就是两层for循环一个一个比较。时间复杂度为O(n^2).

而事实上这题可以通过数组来实现一个简单的哈希表,对于每个字母我们记录它对应的位置以及出现的次数,最后判断数组中所有元素是否为0即可。时间复杂度为O(n),空间上因为定义是的一个常量大小的辅助数组,所以空间复杂度为O(1)。

操作动画如下:

242.有效的字母异位词

1.2 代码实现
class Solution {
    public boolean isAnagram(String s, String t) {
        //定义一个容纳26个字母的数组
        int[] record = new int[26];
        for(int i = 0;i < s.length();i++){
            record[s.charAt(i) - 'a']++;
        }//得到的数组就是包含s每个字母的出现次数
        for(int i = 0;i < t.length();i++){
            record[t.charAt(i)  - 'a']--;
        }
        for(int count : record){
            if (count != 0){
                return false;
            }
        }
        return true;
    }
}
1.3 收获总结
  • 理解下标的含义,因为字符a到字符z的ASCII是26个连续的数值,所以字符a映射为下标0,相应的字符z映射为下标25

2.两个数组的交集

难度:🔥🔥

2.1 思路分析

这题主要考察我们对Set集合的使用,这里我们使用Set的主要实现类HastSet, 并且HashSet的无序性可以帮助我们做去重操作。在JDK7时HashSet的底层实现为数组+链表的形式。

思路如图所示:

set哈希法
2.2 代码实现

数组方式

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
		Set<Integer> set = new HashSet<>();//去重
        int[] record = new int[1005];
        for(int i = 0; i < nums1.length;i++){
            record[nums1[i]] = 1;
        }
        for(int i = 0;i < nums2.length;i++){
            if (record[nums2[i]] == 1){
                set.add(nums2[i]);
            }
        }
        return set.stream().mapToInt(x -> x).toArray();
    }
}

HashSet方式

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

        for(int count : nums1){
            set1.add(count);
        }

        for(int count : nums2){
            if (set1.contains(count)){
                set2.add(count);
            }
        }
        return set2.stream().mapToInt( x -> x).toArray();
2.3 总结收获
  • 使用数组来做哈希的题目,是因为题目都限制了数值的大小
  • 如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费
  • return set2.stream().mapToInt( x -> x).toArray();这里还不是很理解,主要是通过stream().mapToInt(x -> x)得到了IntStream 接口,里面有一个toArray()返回int[],得到最终结果。等后面把Stream和lambada表达式练熟了可以再来看看。

3.快乐数

难度:🔥🔥🔥

该用set的时候,还是得用set

3.1 思路分析

问题的关键在于题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现

了解了这一点,快乐数岂不是被我哈希法轻松拿下。

3.2 代码实现
class Solution {
    public boolean isHappy(int n) {
        Set<Integer> set = new HashSet<>();
        while(n != 1 && !set.contains(n)){
            set.add(n);
            n = getNextNumber(n);
        }
        if(n == 1){
            return true;
        }
        return false;

    }
    //写一个方法用于计算n每个位置上数的平方和
    private int getNextNumber(int nums){
        int result = 0;
        while(nums > 0){
            int number = nums % 10;
            result += number * number;
            nums = nums / 10;
        }
        return result;
    }
}
3.3 总结收获
  • 关键:当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了

4.两数之和

难度:🔥🔥

4.1 思路分析

很显然暴力解法时间复杂度为O(n ^ 2).

而之前我们使用了数组、Set,这里我们都不用。这里我们使用map来解决这个问题是最合适不过了。同时我们需要明白:

  • map用来做什么
  • map中key和value分别表示什么

过程如图:

过程一 过程二
4.2 代码实现

代码虽然简短,但是需要理解每句话代表什么意思,而不能死记硬背

class Solution {
    public int[] twoSum(int[] nums, int target) {
		int[] result = new int[2];
        Map<Integer,Integer> map = new HashMap<>();
        //key为数组元素,value为数组下标
        for(int i = 0; i < nums.length;i++){
            int temp = target - nums[i];
            if (map.containsKey(temp)){
                result[0] = i;
                result[1] = map.get(temp);
                return result;
            }
            map.put(nums[i],i);
        }
        return new int[2];
    }
}
4.3 收获总结
  • map目的用来存放我们访问过的元素,因为遍历数组的时候,需要记录我们之前遍历过哪些元素和对应的下标,这样才能找到与当前元素相匹配的(也就是相加等于target)
  • map中的key存放数组元素,value为数组下标
  • 要熟悉map中的containsKey、get、put方法的使用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值