算法练习 Day6 | leetcode 242.有效的字母异位词,349. 两个数组的交集,202. 快乐数,1. 两数之和

一、哈希表理论基础

1.概念

  • 哈希表是根据关键码的值而直接进行访问的数据结构,例如数组。
  • 哈希表中关键码就是数组的索引下标,然后通过下标直接访问数组中的元素
  • 一般哈希表都是用来快速判断一个元素是否出现集合里

2.哈希碰撞

  • 拉链法
  • 线性探测法

3.常见的哈希结构

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

4.Java实现哈希表

set

  • HashSet用于需要快速查找元素时
  • TreeSet用于需要对元素进行排序时
  • LinkedHashSet用于需要保持插入顺序时

HashSet

  • add(E element): 添加元素到集合中。
  • remove(Object element): 从集合中移除指定的元素。
  • contains(Object element): 检查集合中是否包含指定的元素。
  • size(): 返回集合中的元素个数。

TreeSet

  • add(E element): 添加元素到集合中。
  • remove(Object element): 从集合中移除指定的元素。
  • contains(Object element): 检查集合中是否包含指定的元素。
  • size(): 返回集合中的元素个数。
  • first(): 返回集合中的第一个元素。
  • last(): 返回集合中的最后一个元素。

LinkedHashSet

  • add(E element): 添加元素到集合中。
  • remove(Object element): 从集合中移除指定的元素。
  • contains(Object element): 检查集合中是否包含指定的元素。
  • size(): 返回集合中的元素个数。

map

  • 使用 key value结构来存放key来存元素,value来存下标

hashmap

  • clear() : 删除 hashMap 中的所有键/值对
  • put(K key,V value) :增添数据
  • remove(Object Key) :根据键删除键值对元素
  • void clear()    移除所有的键值对元素
  • boolean containsKey(Object key) :判断集合是否包含指定的键
  • boolean containsValue(Object value) :判断集合是否包含指定的值
  • boolean isEmpty():判断集合是否为空
  • get(Object key)():根据键获取值
  • Set keySet()    获取所有键集合

5.适用情况 

  • 当需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,第一时间想到哈希法。

二、算法题

242.有效的字母异位词

题目链接

class Solution {
    public boolean isAnagram(String s, String t) {
        int []result=new int[26];
        for(int i=0;i<s.length();i++){
            result[s.charAt(i)-'a']++;
        }
        for(int i=0;i<t.length();i++){
            result[t.charAt(i)-'a']--;
        }
        for(int i=0;i<26;i++){
            if(result[i]!=0){
                return false;
            }
        }
        return true;

    }
}
  • s.charAt(i)-'a'能在不知道a的ASCII码时,仍然可以从0到25进行排列
  • 因为如果是'a',那'a'-'a'=0,a就从0开始,'b'会从1开始,'c'会从2开始,以此类推

349. 两个数组的交集

题目链接

方法一:使用set
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Set<Integer> set1=new HashSet<>();
        Set<Integer> set2=new HashSet<>();
        Set<Integer> result=new HashSet<>();
        //把nums1和nums2的数值分别加入到哈希表中
        for(int num:nums1){
            set1.add(num);
        }
        for(int num:nums2){
            set2.add(num);
        }
        //set1更长
        if(set1.size()>set2.size()){
            //遍历Set1中的所有元素
            for(int num:set1){
                //set2中包含set1中的元素
                if(set2.contains(num)){
                    result.add(num);
                }
            }
        }
        else{
            //遍历Set2中的所有元素
            for(int num:set2){
                //set1中包含set1中的元素
                if(set1.contains(num)){
                    result.add(num);
                }
            }
        }
        int []res=new int[result.size()];
        int j=0;
        for(int num:result){
            res[j]=num;
            j++;
        }
        return res;
    }
}
  • 因为题目要求返回的是int数组,所以最后要把哈希set转化为int数组 
方法二:使用数组
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        //数组
        int [] arr1=new int [1002];
        int [] arr2=new int [1002];
        for(int num:nums1){
            arr1[num]++;
        }
        for(int num:nums2){
            arr2[num]++;
        }
        List<Integer> arr3=new ArrayList<>();
        for(int i=0;i<1002;i++){
            if(arr1[i]!=0&&arr2[i]!=0){
                //要找的是对应的下标,因为下标才是给定数组里重复的元素
                //arr3下标对应的数字是这个重复元素出现的次数
                arr3.add(i);
            }
        }
        int []res=new int[arr3.size()];
        int j=0;
        for(int num:arr3){
            res[j]=num;
            j++;
        }
        return res;
    }
}
  • 哈希表解法是用哈希表去重然后找两个哈希表里的相同元素
  • 数组解法是在对应数字的位置++,最后找两个数组里数字位置都不为0的数字

202. 快乐数

题目链接

class Solution {
    public boolean isHappy(int n) {
        Set<Integer> res=new HashSet<>();
        //说明既没有得到1也不是重复出现过的数字,也就是继续循环
        while(n!=1&&!res.contains(n)){
            //把这个新数字添加到哈希表中
            res.add(n);
            n=getnum(n);
        }
        //如果n=1,说明是找到了才退出循环的,此时返回true
        //如果n!=1,说明是出现了重复元素,也就是会陷入死循环,返回false
        return n==1;
        

    }
    //对数字进行处理
    public int getnum(int n){
        int sum=0;
        int i=0;
        while(n>0){
            i=n%10;
            sum+=i*i;
            n=n/10;
        }
        return sum;
    }
}
  • 一个元素重复出现说明会进入死循环的原因如下 

1. 两数之和

题目链接

class Solution {
    public int[] twoSum(int[] nums, int target) {
        //因为题目要求两个整数
        int []res=new int[2];
        if(nums==null){
            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[0]=i;
                res[1]=map.get(temp);
                return res;
            }
            //如果没找到,则把元素加入到哈希表中,进入下一次循环
            map.put(nums[i],i);
        }
        return res;
    }
}

三、其他 

List

  • ArrayList:基于动态数组实现,支持随机访问和快速遍历,适用于读取和修改操作较多的场景。
  • LinkedList:基于双向链表实现,支持高效的插入和删除操作,适用于频繁的插入和删除操作。
  • Vector:与ArrayList类似,但是线程安全,适用于多线程环境。

ArrayList

  • add(E element): 在列表的末尾添加元素
  • get(int index): 获取指定索引位置的元素
  • set(int index, E element): 替换指定索引位置的元素
  • remove(int index): 移除指定索引位置的元素
  • size(): 返回列表的大小

LinkedList

  • add(E element): 在列表的末尾添加元素
  • get(int index): 获取指定索引位置的元素
  • set(int index, E element): 替换指定索引位置的元素
  • remove(int index): 移除指定索引位置的元素
  • size(): 返回列表的大小

Vector

  • add(E element): 在列表的末尾添加元素
  • get(int index): 获取指定索引位置的元素
  • set(int index, E element): 替换指定索引位置的元素
  • remove(int index): 移除指定索引位置的元素
  • size(): 返回列表的大小
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值