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

学习任务:


Leetcode242.有效的字母异位词

难度:简单 | 相关标签:哈希表、字符串、排序

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

  • 思路: 数组其实就是一个简单哈希表,而且这道题目中字符串只有小写字符,那么就可以定义一个数组,来记录字符串s里字符出现的次数。定义一个数组叫做record用来上记录字符串s里字符出现的次数。

    • 需要把字符映射到数组也就是哈希表的索引下标上,因为字符a到字符z的ASCII是26个连续的数值,所以字符a映射为下标0,相应的字符z映射为下标25。
    • 再遍历 字符串s的时候,只需要将 s[i] - ‘a’ 所在的元素做+1 操作即可,并不需要记住字符a的ASCII,只要求出一个相对数值就可以了。 这样就将字符串s中字符出现的次数,统计出来了。
    • 那看一下如何检查字符串t中是否出现了这些字符,同样在遍历字符串t的时候,对t中出现的字符映射哈希表索引上的数值再做-1的操作。
    • 那么最后检查一下,record数组如果有的元素不为零0,说明字符串s和t一定是谁多了字符或者谁少了字符,return false。
    • 最后如果record数组所有元素都为零0,说明字符串s和t是字母异位词,return true。
  • 注意:

    1. 定一个数组叫做record,大小为26 就可以了,初始化为0,因为字符a到字符z的ASCII也是26个连续的数值。
    2. 并不需要记住字符a的ASCII,只要求出一个相对数值就可以了
  • 代码: 数组做哈希表

class Solution {
    public boolean isAnagram(String s, String t) {
        int record[] = new int[26];

        for(int i = 0; i < s.length(); i++){
            record[s.charAt(i) - 'a']++;
        } 

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

        for(int i : record){
            if(i != 0){
                return false;
            }
        }
        return true;
    }
}
  • 反思: 关键在于要意识到要用哈希表的方法解这道题,选用数组存储。

Leetcode349. 两个数组的交集

难度:简单 | 相关标签:数组、哈希表、双指针、二分查找、排序

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

  • 思路: 将nums1 转化为哈希表的形式,用nums2 跟哈希表对比,如果nums2 中的元素在哈希表中出现过,就将这个元素放进result集合里,最后返回 result

  • 注意:

    1. 最后返回的类型是数组类型,如果用set作为结果集,记得转化为数组形式
    2. 题中对数组的长度和值的大小做出了约束,因此也可以用数组做哈希表
  • 代码:
    set 做哈希表

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Set<Integer> set = new HashSet<>();
        Set<Integer> result = new HashSet<>();
        // 将nums数组转换为一个set集合
        for(int i : nums1){
            set.add(i);
        }
        // 遍历nums2数组的过程中判断哈希表中是否存在该元素
        for(int i : nums2){
            if(set.contains(i)){
                result.add(i); // set类型可以自动去重
            }
        }
        // 返回值类型为数组,将result 转成数组
        int[] arr = new int[result.size()];
        int j = 0;
        for(int i : result){
            arr[j] = i;
            j++;
        }
        return arr;

    }
}

数组做哈希表

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        int[] hash1 = new int[1002];
        int[] hash2 = new int[1002];
        for(int i : nums1)
            hash1[i]++;
        for(int i : nums2)
            hash2[i]++;
        List<Integer> resList = new ArrayList<>();
        for(int i = 0; i < 1002; i++)
            if(hash1[i] > 0 && hash2[i] > 0)
                resList.add(i);
        int index = 0;
        int res[] = new int[resList.size()];
        for(int i : resList)
            res[index++] = i;
        return res;
    }
}
  • 反思:

Leetcode202. 快乐数

难度:简单 | 相关标签:哈希表、数学、双指针

  • 题目: 编写一个算法来判断一个数 n 是不是快乐数。

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

  • 注意:

    1. 题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现
  • 代码:

class Solution {
    public boolean isHappy(int n) {
        Set<Integer> set = new HashSet<>();
        set.add(n);
        while(n != 1){
            n = getSum(n);
            if(!set.add(n)){
                return false;
            }
        }
        return true;
    }

    // 计算n每个位置上的数字的平方和
    private int getSum(int n){
        int sum = 0;
        int cur = 0;
        while(n > 0){
            cur = n % 10;
            sum = sum + cur * cur;
            n = n / 10;
        }
        return sum;
    }
}
  • 反思:

Leetcode1. 两数之和

难度:简单 | 相关标签:数组、哈希表

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

  • 思路: 初始化一个Map,用Map存放遍历过的元素。在遍历数组的时候,只需要向map去查询是否有和目前遍历元素匹配的数值,如果有,就找到的匹配对,如果没有,就把目前遍历的元素放进map中,因为map存放的就是我们访问过的元素。

  • 注意:

    1. 本题既要判断数组中的元素,又要找到数组中的下标,因此考虑使用Map做哈希映射 key = 元素,value = 下标
  • 代码:
    暴力破解: 两个for循环嵌套

class Solution {
    public int[] twoSum(int[] nums, int target) {
        for(int i = 0; i < nums.length; i++){
            for(int j = i + 1; j < nums.length; j++){
                if(nums[i] + nums[j] == target){
                    return new int[]{i, j};
                }
            }
        }
        return new int[0];
    }
}

哈希表法:

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] res = new int[2];
        if(nums == null || nums.length == 0){
            return res;
        }
        Map<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < nums.length; i++){
            int temp = target - nums[i];   // 遍历当前元素,并在map中寻找是否有匹配的key
            if(map.containsKey(temp)){
                res[1] = i;
                res[0] = map.get(temp);
                break;
            }
            map.put(nums[i], i);    // 如果没找到匹配对,就把访问过的元素和下标加入到map中
        }
        return res;
    }
}
  • 反思:
  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14训练营中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值