[豪の算法奇妙冒险] 代码随想录算法训练营第六天 | 242-有效的字母异位词、349-两个数组的交集、202-快乐数、1-两数之和

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


LeetCode242 有效的字母异位词

题目链接:https://leetcode.cn/problems/valid-anagram/

文章讲解:https://programmercarl.com/0242.有效的字母异位词.html

视频讲解:https://www.bilibili.com/video/BV1YG411p7BA/?vd_source=b989f2b109eb3b17e8178154a7de7a51

​ 一拿到题目,首先是想构建一个Map,然后发现题目所给字符串只包含小写字母,那其实一个26大小的char数组就够用

​ 解题思路是建立一个大小为26的char数组作为hash表,先遍历字符串s,把出现的字母在数组对应的数值加一,然后再遍历字符串t,把出现的字母在数组对应的数值减一。最后再遍历一遍hash表,若有非零,则说明s和t不是字母异位词

image-20251125090114512

class Solution {
    public boolean isAnagram(String s, String t) {
        char[] dict = new char[26];
        for(int i = 0;i < s.length();i++){
            dict[s.charAt(i) - 'a']++;
        }
        for(int i = 0;i < t.length();i++){
            dict[t.charAt(i) - 'a']--;
        }
        for(int i = 0;i < 26;i++){
            if(dict[i] != 0){
                return false;
            }
        }
        return true;
    }
}

LeetCode349 两个数组的交集

题目链接:https://leetcode.cn/problems/intersection-of-two-arrays/solutions/

文章讲解:https://programmercarl.com/0349.两个数组的交集.html

视频讲解:https://www.bilibili.com/video/BV1ba411S7wu/?spm_id_from=333.1391.0.0&vd_source=b989f2b109eb3b17e8178154a7de7a51

​ 一拿到题目,发现还是用一个hash数组就可以解决:先遍历nums1数组,将nums1中出现的元素在hash数组对应位置进行标记,然后再遍历nums2数组,将nums2命中hash表被标记位置的元素,记录在HashSet里,最后再从HashSet输出成int数组提交即可

image-20251125092753381

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        int[] hash = new int[1001];
        for(int i = 0;i < nums1.length;i++){
            hash[nums1[i]] = 1;
        }

        HashSet<Integer> dict = new HashSet<Integer>();
        for(int i = 0;i < nums2.length;i++){
            if(hash[nums2[i]] == 1){
                dict.add(nums2[i]);
            }
        }

        int[] result = new int[dict.size()];
        int cnt = 0;
        for(Integer i : dict){
            result[cnt] = i;
            cnt++;
        }

        return result;
    }
}

LeetCode202 快乐数

题目链接:https://leetcode.cn/problems/happy-number/description/

文章讲解:https://programmercarl.com/0202.快乐数.html

​ 这题的难点主要在发现不是快乐数的数会陷入循环,且不会越来越大直到无穷大

​ 利用HashSet来记录得到过的数,若再次出现则说明陷入了循环,即不是快乐数

image-20251125104752537

class Solution {
    public boolean isHappy(int n) {
        String str = ((Integer)n).toString();
        HashSet<Integer> dict = new HashSet<Integer>();
        
        while(true){
            int num = 0;
            for(int i = 0;i < str.length();i++){
                num += Math.pow(str.charAt(i) - '0', 2);
            }
            if(num == 1){
                return true;
            }
            if(dict.contains(num)){
                return false;
            }else{
                dict.add(num);
                str = ((Integer)num).toString();
            }
        }
    }
}

​ 看了题解之后发现,还可以用快慢指针来检测是否存在循环,快指针一次移动两个阶段,慢指针一次移动一个阶段,则会出现两种情况:

  • 快指针先到1,说明所给数是快乐数
  • 慢指针与快指针相遇,说明存在循环,不是快乐数

image-20251125105517097

class Solution {
    private int getNext(int n){
        int num = 0;
        while(n > 0){
            int d = n % 10;
            num += d * d;
            n /= 10;
        }
        return num;
    }

    public boolean isHappy(int n) {
        int fast = getNext(n);
        int slow = n;
        while(fast != 1 && fast != slow){
            fast = getNext(getNext(fast));
            slow = getNext(slow);
        }
        return fast == 1;
    }
}

LeetCode1 两数之和

题目链接:https://leetcode.cn/problems/two-sum/description/

文章讲解:https://programmercarl.com/0001.两数之和.html

视频讲解:https://www.bilibili.com/video/BV1aT41177mK/?vd_source=b989f2b109eb3b17e8178154a7de7a51

​ 首先用的是两层for循环暴力求解,因为数据集没那么大所以侥幸通过,但还得再继续优化优化,对于这题O(n^2)还是不够优雅

image-20251125110632684

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

​ 听了Carl哥的讲解,发现用HashMap存已遍历的数和对应下标,for循环遍历到一个新的元素nums[i],就在HashMap里找有没有 target-nums[i] ,这样用一层for循环就做完了之前两层for循环的事,很妙呀

image-20251125200742420

class Solution {
    public int[] twoSum(int[] nums, int target) {
        HashMap<Integer,Integer> dict = new HashMap<Integer,Integer>();
        int[] result = new int[2];
        for(int i = 0;i < nums.length;i++){
            if(dict.containsKey(target-nums[i])){
                result[0] = dict.get(target-nums[i]);
                result[1] = i;
                return result;
            }else{
                dict.put(nums[i],i);
            }
        }
        return result;
    }
}
posted @ 2025-11-25 20:11  SchwarzShu  阅读(7)  评论(0)    收藏  举报