首页 > 其他分享 >代码随想录训练营|Day 6|哈希表理论基础 ,242, 349, 202, 1

代码随想录训练营|Day 6|哈希表理论基础 ,242, 349, 202, 1

时间:2022-09-27 05:22:06浏览次数:82  
标签:return https nums int 随想录 Day 哈希 com 349

Hash table

一般哈希表都是用来快速判断一个元素是否出现集合里。

例如要查询一个名字是否在这所学校里。

要枚举的话时间复杂度是O(n),但如果使用哈希表的话, 只需要O(1)就可以做到。

Hash Function
通过hashCode把名字转化为数值,一般hashcode是通过特定编码方式,可以将其他数据格式转化为不同的数值,这样就把学生名字映射为哈希表上的索引数字了。

Hash Colision
如果学生的数量大于哈希表的大小怎么办,此时就算哈希函数计算的再均匀,也避免不了会有几位学生的名字同时映射到哈希表同一个索引下标的位置。

  • 发生冲突的元素都被存储在链表中
  • 保证tableSize大于dataSize, 依靠哈希表中的空位来解决碰撞问题

常见的三种哈希结构

  • 数组
  • set (集合)
  • map(映射)

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

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

For Future References

文章讲解:https://programmercarl.com/哈希表理论基础.html


242. Valid Anagram

Given two strings s and t, return true if t is an anagram of s, and false otherwise.

An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

Example 1:

Input: s = "anagram", t = "nagaram"
Output: true

Example 2:

Input: s = "rat", t = "car"
Output: false

Constraints:

  • 1 <= s.length, t.length <= 5 * 104
  • s and t consist of lowercase English letters.

Follow up: What if the inputs contain Unicode characters? How would you adapt your solution to such a case?

暴力的解法,两层for循环,同时还要记录字符是否重复出现,很明显时间复杂度是 O(n^2)。

数组其实就是一个简单哈希表,而且这道题目中字符串只有小写字符,那么就可以定义一个数组,来记录字符串s里字符出现的次数。

定一个数组叫做record,大小为26 就可以了,初始化为0,因为字符a到字符z的ASCII也是26个连续的数值。

record用来上记录字符串s里字符出现的次数。
遍历 字符串s的时候,只需要将 s[i] - ‘a’ 所在的元素做+1 操作即可,并不需要记住字符a的ASCII,只要求出一个相对数值就可以了。 这样就将字符串s中字符出现的次数,统计出来了。
在遍历字符串t的时候,对t中出现的字符映射哈希表索引上的数值再做-1的操作。
最后检查一下,

  • record数组如果有的元素不为零0,说明字符串s和t一定是谁多了字符或者谁少了字符,return false。
  • record数组所有元素都为零0,说明字符串s和t是字母异位词,return true。
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']++;
        }

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

Time Complexity:O(n)
Space Complexity:O(1)

For Future References

题目链接:https://leetcode.com/problems/valid-anagram/

文章讲解: https://programmercarl.com/0242.有效的字母异位词.html

视频讲解:https://www.bilibili.com/video/BV1YG411p7BA/


349. Intersection of Two Arrays

Given two integer arrays nums1 and nums2, return an array of their intersection. Each element in the result must be unique and you may return the result in any order.

Example 1:

Input: nums1 = [1,2,2,1], nums2 = [2,2]
Output: [2]

Example 2:

Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
Output: [9,4]
Explanation: [4,9] is also accepted.

Constraints:

  • 1 <= nums1.length, nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 1000

输出结果中的每个元素一定是唯一的,也就是说输出的结果的去重的, 同时可以不考虑输出结果的顺序
暴力的解法时间复杂度是O(n^2)
如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。

import java.util.HashSet;
import java.util.Set;

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<>();
        //遍历数组1
        for (int i : nums1) {
            set1.add(i);
        }
        //遍历数组2的过程中判断哈希表中是否存在该元素
        for (int i : nums2) {
            if (set1.contains(i)) {
                resSet.add(i);
            }
        }
        //将结果几何转为数组
        return resSet.stream().mapToInt(x -> x).toArray();
    }
}

Time Complexity:O(n)
Space Complexity:O(n)

For Future References

题目链接:https://leetcode.com/problems/intersection-of-two-arrays/

文章讲解: https://programmercarl.com/0349.两个数组的交集.html

视频讲解:https://www.bilibili.com/video/BV1ba411S7wu/


202. Happy Number

Write an algorithm to determine if a number n is happy.

happy number is a number defined by the following process:

  • Starting with any positive integer, replace the number by the sum of the squares of its digits.
  • Repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1.
  • Those numbers for which this process ends in 1 are happy.

Return true if n is a happy number, and false if not.

Example 1:

Input: n = 19
Output: true
Explanation:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1

Example 2:

Input: n = 2
Output: false

Constraints:

  • 1 <= n <= 231 - 1

题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要!
所以这道题目使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。

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

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

For Future References

题目链接:https://leetcode.com/problems/happy-number/

文章讲解: https://programmercarl.com/0202.快乐数.html


1. Two Sum

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

You can return the answer in any order.

Example 1:

Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].

Example 2:

Input: nums = [3,2,4], target = 6
Output: [1,2]

Example 3:

Input: nums = [3,3], target = 6
Output: [0,1]

Constraints:

  • 2 <= nums.length <= 104
  • 109 <= nums[i] <= 109
  • 109 <= target <= 109
  • Only one valid answer exists.

Follow-up:

Can you come up with an algorithm that is less than O(n^2) time complexity?

暴力的解法是两层for循环查找,时间复杂度是O(n^2)。

需要一个集合来存放我们遍历过的元素,然后在遍历数组的时候去询问这个集合,某元素是否遍历过,也就是 是否出现在这个集合。
我们不仅要知道元素有没有遍历过,还有知道这个元素对应的下标,需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map正合适。

  • 数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。
  • set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x 和 y的下标。所以set 也不能用。

此时就要选择另一种数据结构:map ,map是一种key value的存储结构,可以用key保存数值,用value在保存数值所在的下标。

map目的用来存放我们访问过的元素,因为遍历数组的时候,需要记录我们之前遍历过哪些元素和对应的下表,这样才能找到与当前元素相匹配的(也就是相加等于target)

{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);
        }
        map.put(nums[i], i);
    }
    return res;
}

Time Complexity:O(n)
Space Complexity:O(n)

For Future References

题目链接:https://leetcode.com/problems/two-sum/

文章讲解: https://programmercarl.com/0001.两数之和.html

视频讲解:https://www.bilibili.com/video/BV1aT41177mK/

标签:return,https,nums,int,随想录,Day,哈希,com,349
From: https://www.cnblogs.com/bluesociety/p/16733165.html

相关文章

  • 代码随想录day6 | 242. 有效的字母异位词 349.两个数组的交集 202.快乐数1.两数之和
    242.有效的字母异位词题目|文章1.哈希思路字母的异位词意味着两个词中字符的种类和次数都相等。因为只有26个字符,所以我们可以通过数组实现一个26位的哈希表。先记录一......
  • Day 12 synchronized和Lock的学习
    Day12多线程学习同步方法及同步块方法锁synchronized可以保证线程的同步。形成原理就是队列和锁在方法前加synchronized关键字这个方法就是同步方法,没有加就不安全。......
  • day02 cookie管理器
    1、添加默认请求头2、配置好http请求:get请求和路径/cookie/set,添加参数:uesr:uesername3、添加配置元件-cookie管理器4、添加结果树5、提交请求,查看结果树,get请求体里面,......
  • day06
    leetcode242.有效的字母异位词进入哈希表章节思路:首先数组本身就是一个简单的哈希表,我们可以利用一个数组来记录元素出现的次数,字母一共有26个,我们可以定义一个长度为26......
  • Jvm(day3—内存模型)
    Jvm内存模型 名称说明方法区存储:类的元信息、静态变量、常量jdk1.8之后,用元空间替换了方法区,且元空间的内存不在jvm中,而是用的本地内存。堆区存储:对象......
  • python学习day04
    上周内容回顾PEP8规范1.井号后跟注释文字时,井号和前面的代码空两格,和后面的注释文字空一格。2.井号单独起一行后跟注释文字时,和后面的注释文字空一格。3.列表、......
  • python小白入门学习day04
    python小白入门学习day04目录§一、周末内容回顾1、PEP8规范2、python注释语法3、变量与常量4、数据类型§二、今日内容详细1、作业详解2、基本数据类型之布尔值bool2、基......
  • day04
    今日内容总结常见的数据类型补充布尔值bool用途:用于表达事物对错以及是否可行用于流程控制1.存在状态true对的可行的false错的不可行的......
  • Java 狂神 Day01 Windows快捷键
    Windows快捷键ctrl+E:打开我的电脑ctrl+shift+esc:打开任务管理器alt+F4:关闭窗口alt+tab:切换窗口shift+del:永久删除win+D:返回桌面 ......
  • 学习python-Day64
    回顾补充知识http请求应用层:基于tcp/ip之上是进行网络传输,广泛用于前后端的交互请求协议:请求首行请求方式:get、post,请求地址:get携带数据,请求协议,请求版本......