day6 | 242 有效的字母异位词,349 两个数组的交集,202 快乐数,1 两数之和

文章探讨了几种常见的编程算法问题,包括如何判断两个字符串是否为字母异位词,通过哈希表或数组实现两个数组的交集,判断快乐数的方法,以及解决两数之和的问题。这些方法利用了哈希集合(HashSet)和哈希映射的特性,提高了算法效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

242 有效的字母异位词

思路

定义一个有26个位置的数组,因为字母共有26个
对于单词s和t, 在扫描s的时候,记录每个单词出现的个数保存到数组
在扫描s的时候,操作同一个数组,对出现的每个字母对应的数组上所保存的个数上进行减减操作
如果数组最后所有位置上全为0,说明s和t互为异位词

题解

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']++;     // 并不需要记住字符a的ASCII,只要求出一个相对数值就可以了
        }

        for (int i = 0; i < t.length(); i++) {
            record[t.charAt(i) - 'a']--;
        }
        
        for (int count: record) {
            if (count != 0) {               // record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。
                return false;
            }
        }
        return true;                        // record数组所有元素都为零0,说明字符串s和t是字母异位词
    }
}

349 两个数组的交集

思路

首先将数组1的值存到Set1中,然后遍历数组2,如果数组2中的值在Set1中出现,那么将值存到Set2中,最后将Set2中的值存到新数组并返回。
注意:
set不仅占用空间比数组大,而且速度比数组慢,因为set把数值映射到key上都要做hash计算的。在数据量大的情况下,差距会很明显。

数组作哈希表-题解

因为数据范围为 0 <= num1[i], num2[i] <= 1000,所以可以使用数组来做哈希表。

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Set<Integer> resSet = new HashSet<>();
        int[] hash = new int[1010];

        for (int i : nums1){
            hash[i] = 1;
        }

        for (int i : nums2){
            if (hash[i] == 1){
                resSet.add(i);
            }
        }

        int[] resArr = new int[resSet.size()];
        int j = 0;
        for(int i : resSet){
            resArr[j ++] = i;
        }

        return resArr;
    }
}

HashSet-题解

java中HashSet的特点:
1)HashSet实现了Set接口
2)HashSet实际上是HashMap
3)可以存放null值,但是只能有一个null
4)HashSet不保证元素是有序的,取决于hash后,再确定索引的结果即不保证存放元素的顺序和取出元素一致
5) 不能有重复元素/对象
分割线

  1. HashSet 底层是 HashMap
    2.添加一个元素时,先得到hash值-会转成-> 索引值
    3.找到存储数据表table,看这个索引位置是否已经存放的有元素
    4.如果没有,直接加入
    5.如果有,调用equals 比较,如果相同,就放弃添加,如果不相同,则添加到最后
    6.在Java8中,如果一条链表的元素个数超过 TREEIFY THRESHOLD(默认是8),并且table的大小

=MIN_TREEIFY_CAPACITY(默认64),就会进行树化(红黑树)

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        if (nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0){
            return new int[0];
        }

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

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

        for (int i : nums2){
            if (set1.contains(i)){
                resSet.add(i);
            }
        }

        int[] resArr = new int[resSet.size()];
        int j = 0;
        for (int i : resSet){
            resArr[j++] = i;
        }

        return resArr;
    }
}

快乐数

思路

如果出现了无限循环,说明在求和的过程中,sum会重复出现。那么我们每次保存sum的值,使用HashSet保存,在保存之前判断sum是否已经存在,如果存在,说明出现了无限循环,那么return n == 1来判断n是否为快乐数。

题解

class Solution {
    public boolean isHappy(int n) {
        Set<Integer> record = new HashSet<>();
        while (!record.contains(n)){
            record.add(n);
            n = getNextNum(n);
        }
        return n == 1;
    }

    private int getNextNum(int n){
        int res = 0;
        while (n > 0){
            int temp = n % 10;
            res += temp * temp;
            n = n / 10;
        }
        return res;
    }
}

1 两数之和

思路

题目要求返回满足条件的数组索引位置
使用map存入,key存数组值,value存数组下标。
在遍历数据的时候,每遍历一个,把遍历过的数值存到map的key里,下标存到map的value里
在存入之间,在map里查找是否有target-nums[i]的值,因为是对值查找,所以map的key存放数值

题解

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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值