代码训练营day06

哈希法

组成:包括数组、Set集合、Map

选择:我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。

但是哈希法也是牺牲了空间换取了时间

一、字母异位分组

1. 就是比较某个字母出现的次数一不一致,但是因为英文字母并不能直接当数组的索引,利用char和英文字母相邻的性质,转换成索引。

2. 统计次数时,并没有传统的比较两个字母出现的次数一不一致,而是直接通过在同一个数组相加减的方式,进行标识,从而减少了新建数组的麻烦。

class Solution {
    public boolean isAnagram(String s, String t) {
       // 用来记录26个字母的次数
       int [] record = new int[26];

       for(int i =0 ; i<s.length();i++){
        // todo 这段代码是关键 
        record[s.charAt(i) - 'a']++;  // 利用char类型和英文小写字母的特点,巧妙的用数组存储了
       }

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

    
}

}

二、两个数组的交集

这道题和上道题很像,也要找相同的数,但是这道题需要求相同的数,因此需要转换列表用来存储数据,再转换成数组

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

        }
        int count = 0;
        for(int i = 0;i<nums2.length;i++){
            hash2[nums2[i]] = 1;
        }

        // 用列表的原因在于,不知道到底有多少个元素
        List<Integer> list = new ArrayList<>();
        for(int i = 0;i<1001;i++){
            if(hash1[i] >0 && hash2[i] > 0){
                list.add(i);
            }
        }
        // 列表转换成数组
        int[] arr = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            arr[i] = list.get(i);
        }

        return arr;
    }
}

三、快乐数

关键点:标准n为1,只要一出现以前的数,则排除掉

public class HappyData {
    public boolean isHappy(int n) {
        Set<Integer> set = new HashSet<>();    // 去重,防止出现无限循环

        while(n!=1 && !set.contains(n)){
            set.add(n);
            n = sumOfSquares(n);
        }
        return n == 1;
    }
    // 计算一个数的每个数字的平方和
    public static int sumOfSquares(int num) {
        int sum = 0;
        while (num != 0) {
            int digit = num % 10;
            sum += digit * digit;
            num /= 10;
        }
        return sum;
    }
}

四、两数之和

这里选择用Map,因为需要数据和返回索引

public class TwoSum {
    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;
    }

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值