代码随想录Day6

题目列表

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

解题过程

242.有效的字母异位词

题目描述

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的 字母异位词。

示例 1:
输入: s = "anagram", t = "nagaram"
输出: true
示例 2:
输入: s = "rat", t = "car"
输出: false
提示:
1 <= s.length, t.length <= 5 * 104
s 和 t 仅包含小写字母

解题思路

字母异位词,根据题意来看也就是两个字符串中出现的字母完全相同。要判断一个字符串中的每个字母是否在另一个字符串的字母集合中出现过,考虑用哈希法。
因为题目给出全部是小写字母,小写字母一共有26个,比较小,可以用数组。hashCode 可以是该字符的ASCII码与 'a'的 ASCII码的差,这样26个字母都拥有各自对应的索引下标。
s 中出现一次某个字母,哈希表中对应位置就加 1,遍历一遍 s ;然后遍历一遍 t, t 中出现一次某个字母,哈希表对应位置就减 1,两个字符串都扫描一遍后,看哈希表里的元素是不是都是 0,如果是的话,那么说明这两个字符串的字母完全相同。

代码展示

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

        for(int i = 0;i < s.length(); i++){
            table[s.charAt(i) - 'a']++;
        }
        for(int i = 0;i < t.length(); i++){
            table[t.charAt(i) - 'a']--;
        }
        for(int i = 0;i < 26; i++){
            if(table[i] != 0) return false;
        }
        return true;
    }
}

349.两个数组的交集

题目描述

给定两个数组 nums1 和 nums2 ,返回 它们的 交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的
提示:
1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000

解题思路

求数组交集,也就是看某些元素有没有在两个数组中都出现过,考虑哈希法。而且返回的是交集,需要去重。
题目限制了数组元素的范围0 <= nums1[i], nums2[i] <= 1000,那么就可以使用数组作为哈希表,去重操作由我们手动来做,保证不要重复记录即可。
假如不限制数组元素范围,那么就不能用数组了,这时候考虑 set 集合,因为它自带去重功能,Java 中的HashSet 是一个基于哈希表实现的集合类,很适用。

代码展示

//HashSet
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        if(nums1 == null || nums2 == null || nums1.length == 0 || nums2.length == 0){
            return new int[0];
        }
        Set<Integer> set1 = new HashSet<>();
        Set<Integer> result = new HashSet<>();
        for(int i : nums1){
            set1.add(i);
        }
        for(int i : nums2){
            if(set1.contains(i)){
                result.add(i);
            }
        }
        int[] res = new int[result.size()];
        int j = 0;
        for(int i : result){
            res[j++] = i; 
        }
        return res;
    }
}
//数组
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        int[] serach = new int[1005];
        List<Integer> res = new ArrayList<>();
        for(int i : nums1){
            serach[i] = 1;
        }
        for(int j : nums2){
            if(serach[j] == 1){
                res.add(j);
                serach[j] = -1;
            }
        }
        int result[] = new int[res.size()];
        int index = 0;
        for(int i : res){
            result[index++] = i;
        }
        return result;
    }
}

202.快乐数

题目描述

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

解题思路

  • 两个终止条件:
    sum == 1 或者 sum 开始重复出现。
    sum 重复出现这个情况就可以用哈希法来快速判断,数值范围未知,因此不能用数组,考虑 HashSet.
  • 判断过程:
    先判断当前 sum 是不是 1,或者sum 是不是已经在之前出现过,如果是则根据对应情况返回 true 或 false;
    如果 sum 还不满足以上条件,就把这个 sum 加入集合中,然后更新 sum 为每一位的平方的和,再进行下一轮判断。

注意事项

如果不是快乐数的话,这个数本身也在循环之中,所以要注意while中的语句顺序。

代码展示

class Solution {
    public boolean isHappy(int n) {
        Set<Integer> table = new HashSet<>();
        while(n != 1 && !table.contains(n)){
            table.add(n);
            n = getNextNumber(n);
        }
        return n == 1; 
    }
    private int getNextNumber(int x){
        int res = 0;
        //从个位平方和开始累加
        while( x > 0){
           int temp = x % 10;
           res += temp*temp;
           x = x / 10;
        }
        return res;
    }
}

1.两数之和

题目描述

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]

提示:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案

解题思路

这道题有两个要求的点,第一个是判断数组中是否存在两个数相加为 target, 第二个是要记录这两个数字的下标并返回。

  • 对于第一点,可以想到要用哈希法,因为是在同一个数组中找两个加起来等于 target 的数,而且它们唯一,还不允许自己和自己相加,那么其实只用扫描一遍就足够了,判断 “target - 当前数”是否已经记录在哈希表中,存在就相当于已经找到了答案,不存在就将当前数记录在哈希表中,考虑最坏的情况,最后一个元素才是正确的解的一部分,那它的“另一半”也一定被记录在哈希表中了。
  • 对于第二点,我们需要维护数组中元素和索引的对应关系,那么集合就不适用了,与此同时,题目中给出数字的范围非常大,那么二维数组也就不适用了,所以考虑用 HashMap 实现哈希表。

代码展示

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer,Integer> index = new HashMap<>();
        for(int i = 0; i < nums.length; i++){
            int temp = target - nums[i];  //另一个符合的值
            if(index.containsKey(temp)){
                return new int [] {i, index.get(temp)};  //存在,返回它们的下标
            }else{
                index.put(nums[i],i);  //不存在,index保存所有已经遍历的数组下标
            }
        }
        return null;
    }
}

参考资料

代码随想录

posted @ 2025-04-28 12:42  cbdsszycfs  阅读(369)  评论(0)    收藏  举报