随想录训练营Day6|哈希表 242.有效的字母异位词, 349. 两个数组的交集,202. Happy Number,1. 两数之和

66 阅读4分钟

随想录训练营Day6|哈希表 242.有效的字母异位词, 349. 两个数组的交集,202. Happy Number,1. 两数之和

标签: LeetCode闯关记


##哈希表(Hash Table) 当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法 常见的数据结构:

array;set;map; ##1. 242.有效的字母异位词 ###1.1 题目 相关链接: 242.有效的字母异位词

###1.2 解题思路 ①编写函数来判断t是否是s的字母异位词,可以看作判断字母是否出现在某个集合中_____考虑用hashSet;

②字母个数确定,题目描述可以把字符串假设为只包含小写字母,可以考虑用最简单的hashSet,即数组; ###1.3 遇到问题 无 ###1.4 算法实现

class Solution {
    public boolean isAnagram(String s, String t) {
        int[] record = new int[26];//26个字母数所以数组长度固定
        //两次遍历并用新数组record记录便能够进行对比
        for (int i = 0; i < s.length(); i++){
            record[s.charAt(i) - 'a']++;
        }//不必记录精确的ASCII码,用[s.charAt(i) - 'a']即可
        for (int j = 0; j < t.length(); j++){
            record[t.charAt(j) - 'a']--;
        }
        for (int n : record) {
            if(n != 0){
                return false;
            }
        }
        return true;
    }

注意点:待更新

###1.5 题目总结 解题耗时:30min ###1.6 相关题目 383.赎金信

49.字母异位词分组

438.找到字符串中所有字母异位词


##**2. 349. 两个数组的交集 ** ###2.1 题目 题目:349. 两个数组的交集 ###2.2 解题思路 题目:Each element in the result must be unique and you may return the result in any order. 引入新的构造体:SET SET基本介绍: 1.无序(添加和取出的顺序不一致),没有索引; 2.不允许重复元素,所以最多只能包含一个null; 详见:韩顺平java(可补充链接) 用到的方法: set.add(); set.contains();
###2.4 实现代码

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        if(nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0){
            return new int[0];
        }//nums1 == null 和 nums1.length == 0的区别
        Set<Integer> set1 = new HashSet<>();
        Set<Integer> resSet = new HashSet<>();

        //遍历数组1
        for (int number : nums1) {
            set1.add(number);
        }
        //遍历数组2的过程中判断哈希表中是否存在该元素
        for (int i : nums2) {
            if(set1.contains(i)){
                resSet.add(i);
            }
        }
        int[] res = new int[resSet.size()];
        int i = 0;
        //利用迭代器遍历set
        //另外申请一个数组存放setRes中的元素,最后返回数组
        Iterator<Integer> iterator = resSet.iterator();
        while (iterator.hasNext()) {
            int next =  iterator.next();
            res[i] = next;
            i++;
        }
        return res;
    }
}

注意点: nums1 == null 和 nums1.length == 0是两个不同的判断条件,含义也不同。

(优先判断)nums1 == null 判断的是 nums1 是否为 null。 如果 nums1 是 null,则表示该数组变量没有被初始化,即该数组不存在,因此不能对其进行操作,包括读取、修改等。如果试图对其进行操作,会抛出 NullPointerException 异常。

nums1.length == 0 判断的是 nums1 是否为一个长度为0的数组。如果 nums1 是一个长度为0的数组,则表示该数组存在但是其中没有任何元素,可以对其进行读取和修改操作,但是其长度为0,无法进行遍历或者其他需要依赖于数组长度的操作。 ###2.5 题目总结 解题耗时: 40min ###2.6 相关题目 350.两个数组的交集 II


##3. 202. Happy Number ###3.1 题目 相关链接 202. Happy Number

###3.2 解题思路 repeat the process之后有两种情况,it loops endlessly in a cycle which does not include 1(会重复出现除了1之外的其他数) or ends in 1. 难点: 1.采用什么数据结构才能够很好地进行happy number 的计算和判断过程? 2.求和的过程:while循环 ###3.3 遇到问题 无 ###3.4 算法实现

class Solution {
    public boolean isHappy(int n) {
        Set<Integer> record = new HashSet<>();
        while(n != 0 && ! record.contains(n)){
            record.add(n);
            n = getNextNumber(n);
        }
        return n == 1 ? true : false;//等价于 return n == 1;
    }
    private int getNextNumber(int n){
        int temp = 0;
        int sum = 0;
        while(n > 0){
            temp = n % 10;
            sum += temp * temp;
            n = n / 10;
        }
        return sum;
    }
}

注意点: ①退出while循环的条件: n==1(说明是快乐数) 或者 n 出现循环(说明不是快乐数) ②return n == 1:表示 可以返回一个布尔值,因为这个语句使用了一个等于运算符 ==,它的结果要么是 true,要么是 false。具体来说,如果 n 等于1,则等于运算符的结果为 true,否则为 false。 ###3.5 题目总结 解题耗时:30min ###3.6 相关题目


##4. 1. 两数之和 ###4.1 题目 相关链接 1. 两数之和

###4.2 解题思路 1.why use the Map data structure? 首先,遍历数组时.我们需要判断当前遍历的数是否的target -nums[i]被遍历过,if yes,则找到了一组解; 所以,我们需要集合来存放遍历过的数,存放不仅要存元素,还需要存放下标 so, map可用来存放key,value 2. why use the unordered map? 不需要进行排序---HashMap效率更高

Map 实现适用场景时间复杂度
HashMap大部分情况,不需要排序和保持插入顺序的情况平均为 O(1),最坏为 O(n)
TreeMap需要对 key 进行排序的情况平均为 O(log n)
LinkedHashMap需要保持插入顺序的情况平均度为 O(1),最坏为 O(n)
ConcurrentHashMap多线程环境下需要使用的情况平均为 O(1),最坏为 O(log n)
IdentityHashMap需要基于对象引用进行相等性比较的情况与 HashMap 相同

###4.3 遇到问题 无 ###4.4 算法实现

class Solution {
    public int[] twoSum(int[] nums, int target) {
        //新建hashmap
        Map<Integer,Integer> valToIndex = new HashMap<>();
        //遍历数组
        int res = 0;
        for( int i = 0; i < nums.length; i++){
            res = target - nums[i];
            //如果在存放遍历过的元素的hashmap中找到该res,返回
            if(valToIndex.containsKey(res)){
                return  new int[]{valToIndex.get(res),i};
            }else{//没找到的话,把当前遍历的数加入到hashmap中
                valToIndex.put(nums[i],i);
            }
        }
        return null;
    }
}

##5. 今日心得 补3.20