day06 哈希表章节

day06哈希表

总结的来说,当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法

但是哈希法也是牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。

lc242有效的字母异位词

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

示例 1: 输入: s = “anagram”, t = “nagaram” 输出: true

示例 2: 输入: s = “rat”, t = “car” 输出: false

说明: 你可以假设字符串只包含小写字母。

读题可以看不懂到底什么是字母异位词呢?

大白话就是 给定两个字符串 判断是否有相同的字母组成(不管顺序)

比如 abbc — bbac 这这就是一对字母异位词

因为知道这些字母只能是小写字母 而且字母的asc码都是连续的

所以可以定一个数组 大小是26 刚好能放入26个字母 用来记录字符串s里字符出现的次数。

因为asc码都是连续的 所以a到z是26个连续的数 所以将(s[i] - ‘a’)++ 求出来一个数字

同样,在便利t的时候,只需要-- 就可以了

其实也就是26个字母对应26个下标 出现一次就对应下标加一 出现的位置比如

t=‘abcdef…z’ 26个 那么依次加加操作之后就是 arr[1,1,1,1,1,1,1,1,1,1,1,1,…1] 26个1

最后检查这个数组,如果有元素不等于0 说明s或者t字符串一定有一个多了 或者少了

如果都是等于0 说明就是字母异位词

时间复杂度为O(n),空间上因为定义是的一个常量大小的辅助数组,所以空间复杂度为O(1)。

--------

也就是:

第一次便利s的时候 遇到每个字母就把他在数组对应的位置加1 表示出现过

第二次便利t的时候 遇到的时候 就把对应位置减1

如果最后结果数组都是0 代表两个字符串完全相等

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

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

    for(int i = 0; i < t.length(); i++) arr[t.chatAt(i) - 'a']--;

    for(int c : arr){
        if(c != 0) return false;
    }
    return true;
}

lc349两个数组的交集

> 题意:给定两个数组,编写一个函数来计算它们的交集。 > > 输入:nums1 = [4,9,5],nums2 = [9,4,9,8,4] > > 输出:[9,4] >

使用set结构 定义 s1 res

s1 用于存放num1中的元素也就是 s1 = {4,9,5}

res 用于nums1和nums2经过去重之后交集部分

执行结果:

  • nums2[0] = 9s1 包含 9,添加到 resres = {9}
  • nums2[1] = 4s1 包含 4,添加到 resres = {9, 4}
  • nums2[2] = 9res 已经包含 9,所以不重复添加。
  • nums2[3] = 8s1 不包含 8,跳过。
  • nums2[4] = 4res 已经包含 4,所以不重复添加。

最终,res = {9, 4},这是 nums1nums2 的交集。

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

    // 初始化set
    Set<Integer> s1 = new HashSet<>();
    Set<Integer> res = new HashSet<>();

    //便利num1
    for(int i : nums1) s1.add(i);

    // 便利num2时候需要先去重
    for(int i : nums2){
        if(s1.contains(i)) res.add(i);
    }

    //申请新数组存放结果 并且返回
    int[] arr = new int[res.size()];
    int index = 0;
    for(int num : res) arr[index++] = num;
    return arr;
}

lc202 快乐数

「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。

编写一个算法来判断一个数 <font style="color:rgba(38, 38, 38, 0.75);background-color:rgb(240, 240, 240);">n</font> 是不是快乐数。

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

这道题目使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。

public boolean isHappy(int n) {
    Set<Integer> set = new HashSet<>();
    while(n != 1 && set.contains(n)){
        set.add(n);
        n = getNumber(n);

    }
    return n == 1;

}
public int getNumber(int n) {
    int res = 0;
    while(n > 0){
        int temp = n % 10 //取出个位
        res += temp * temp;
        n /= 10; 

    }
    return res;
}


lc1 两数之和

梦的开始!!!

使用map来记录数字和下标

map中的存储结构为 {key:数据元素,value:数组元素对应的下标}。

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];
        if(map.containsKey(temp)){
            res[1] = i;
            res[0] = map.get(temp);
            break;

        }
        map.put(nums[i], i);

    }
    return res;


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值