day5周日休息 day6哈希表part1

什么时候想到用哈希法,当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。
day5周日休息 day6哈希表part1_第1张图片

前置知识:

在java中,可以利用String类的length()方法来获取字符串长度,语法格式为“字符串名.length();”;该方法可以返回字符串的长度,空字符串的长度返回0。
增强for循环(原文链接:https://blog.csdn.net/m0_56392935/article/details/126431091)
Java5引入了一种主要用于数组或集合的增强型for循环
Java增强for循环语法格式如下:
for(声明语句:表达式){
//代码语句
}

声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值于此时数组元素的值相等
表达式:表达式是要访问的数组名,或者是返回值为数组的方法
代码演示

public class Demo02 {
public static void main(String[] args) {
int[] numbers = {10,20,30,40,50}; //定义了一个数组

for (int i = 0; i < 5; i++) {
System.out.println(numbers[i]);
}
System.out.println(“===========================”);
//遍历数组的元素
for (int x:numbers){
System.out.println(x);
}
}
}
day5周日休息 day6哈希表part1_第2张图片
charAt(原文链接:http://t.csdnimg.cn/MewhZ)
day5周日休息 day6哈希表part1_第3张图片
Set接口的特性,Set接口继承了Collection接口,Set集合中不能包含重复的元素,每个元素必须是唯一的,你只要将元素加入set中,重复的元素会自动移除。下面分三方面对它的三个实现类进行说明。
1、HashSet类:HashSet是采用hash表算法来实现的,其中的元素没有按顺序排列,主要有add()、remove()以及contains()等方法;

242. 有效的字母异位词

简单
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

//哈希数组
class Solution {
    public boolean isAnagram(String s, String t) {
        int count[] = new int[26]; //利用数组哈希表来解

        for(int i = 0; i < s.length(); i++){
            count[s.charAt(i) - 'a']++; // 并不需要记住字符a的ASCII,只要求出一个相对数值就可以了
        }
        for(int i = 0; i < t.length(); i++){
            count[t.charAt(i) - 'a']--;
        }

        for(int i : count){
            if (i != 0){ // record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。
                return false;
            }
        }

        return true;
    }
}

349. 两个数组的交集

简单
给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

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

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

        for (int i: nums1){
            set1.add(i);
        }
        //遍历数组2的过程中判断哈希表中是否存在该元素
        for (int i: nums2){
            if (set1.contains(i)){
                resSet.add(i);
            }
        }

        // 另外申请一个数组存放setRes中的元素,最后返回数组
        int[] res = new int[resSet.size()];
        int j = 0;
        for (int i : resSet){
            res[j++] = i;
        }
        return res;
    }
}
  1. 快乐数
    简单
    编写一个算法来判断一个数 n 是不是快乐数。
    「快乐数」 定义为:
    对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
    然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
    如果这个过程 结果为 1,那么这个数就是快乐数。
    如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
    day5周日休息 day6哈希表part1_第4张图片

难点1:

取数值各个位上的单数

难点2:

如何终止这个无限循环,无限循环的意思肯定是有的数又重复了。判断一下以前有没有出现过这样的数即可。

class Solution {
    public boolean isHappy(int n) {
        Set<Integer> hashset = new HashSet<>();

        while (n != 1){
            n = cal(n);
            
            if (hashset.contains(n)){
                return false;
            }else{
                hashset.add(n);
            }
        }
        return true;
    }

    private int cal(int n){ //注意看这块是怎么取各个位上的单数的
        int sum = 0;
        int temp = 0;

        while (n > 0){
            temp = n % 10;
            sum += temp * temp;
            n /= 10;
        }
        return sum;
    }
}

1. 两数之和

简单
提示:给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。

难点

这个题要返回下标,所以不能用set,要用map(要说难点,难就难在我还没学map……)
day5周日休息 day6哈希表part1_第5张图片

思考

//关于为什么要边找边存,而不是先存后找,边找边存会不会有漏掉的?
//边找边存应该是时间和空间复杂度更低的(时间复杂度倒也不一定,只能说数组很长时还是有优势的)
//边找边存肯定不会漏掉的。假设我们的数组中恰好有一对a+b=target,a比b在前
//那么肯定到a时找不到合适的,因为此时b还没加入hash table,那么就会把a加入hash table
//轮到b时,肯定就能把a找出来。边存边找一般都是后面的数找到以前被加入到哈希表里的伙伴

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 destination = target - nums[i];
            if (map.containsKey(destination)){
                res[0] = i;
                res[1] = map.get(destination);
                break;
            }else{
                map.put(nums[i], i);
            }
        }
        return res;
    }
}

你可能感兴趣的:(散列表,数据结构)