代码随想录算法训练营第六天_哈希表 _ 242.有效的字母异位词、349. 两个数组的交集、202. 快乐数、 1. 两数之和 、补160链表相交。

学习目标:

60天训练营打卡计划!

学习内容:

  • 当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法
  • 当我们想使用哈希法来解决问题的时候,我们一般会选择如下三种数据结构。
    • 数组
    • set (集合)
    • map(映射)
  • 引用自代码随想录网站。

242.有效的字母异位词

  • 使用数组来实现对应。
  • 设置一个长度为26的int数组,有对应的字母就++
  • 为了不记忆字母的ASCII码,使用该操作 tmp[s.charAt(i) - ‘a’]
  • String的长度是length(),数组是length
  • s.charAt(i) 是Java中取位置i处字符的函数
class Solution {
    public boolean isAnagram(String s, String t) {
        int[] tmp = new int[26];
        // charAt(i)获取String中位置i的字符
        for(int i = 0; i < s.length(); i++)
            tmp[s.charAt(i) - 'a']++;
        for(int j = 0; j < t.length(); j++)
            tmp[t.charAt(j) - 'a']--;
        for(int i = 0; i < 26; i++)
            if(tmp[i] != 0){
                return false;
            }
        return true;
    }
}

349. 两个数组的交集

  • 使用集合先对第一个数组中的元素去重,再使用第二个数组中的元素与其对比,若包含则放入第二个集合中(去重)!
  • return reset.stream().mapToInt(x -> x).toArray();玩意就比较难
  • 很多Java的集合的基本操作不是很熟悉,还需要多强化。
  • 补充一点点相关的知识
    Set 集合支持的遍历方式和 Collection 集合一样:foreach 和 Iterator。
    Set 的常用实现类有:HashSet、TreeSet、LinkedHashSet。
    • HashSet 按 Hash 算法来存储集合中的元素,因此具有很好的存储、查找、删除性能。
    • HashSet 具有以下特点:
    – 不能保证元素的排列顺序
    – HashSet 不是线程安全的
    – 集合元素可以是 null
    • HashSet 集合判断两个元素相等的标准:两个对象通过 hashCode() 方法得到的哈希值相等,并且两个对象的 equals()方法返回值为 true。
    • 对于存放在 Set 容器中的对象,对应的类一定要重写 hashCode()和 equals(Object obj)方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”。
    • HashSet 集合中元素的无序性,不等同于随机性。这里的无序性与元素的添加位置有关。具体来说:我们在添加每一个元素到数组中时,具体的存储位置是由元素的hashCode()调用后返回的 hash 值决定的。导致在数组中每个元素不是依次紧密存放的,表现出一定的无序性。
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        // Set<Integer> 作为变量类型可以使你的代码更加灵活,因为你可以随时切换不同的 Set 实现类
        Set<Integer> unset = new HashSet();
        Set<Integer> reset = new HashSet();
        for(int i = 0; i < nums1.length; i++){
            unset.add(nums1[i]);
        }
        for(int j = 0; j < nums2.length; j++){
            if(unset.contains(nums2[j]))
                reset.add(nums2[j]);
        }
        // 流中的每个元素进行映射操作。这里x -> x表示将元素映射为它自身。
        //  将流中的元素收集到一个数组中。
        return reset.stream().mapToInt(x -> x).toArray();
    }
}

202. 快乐数

  • 题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要!
  • 需要二刷,并不是很快乐!
  • 两个难点
    • 如何获取int类型值得每一位数据?
    • 使用余数获取各位的数值,使用商对数据做递减。
    • 如何判定循环结束的条件?
    • 无限循环,那么也就是说求和的过程中,sum会重复出现
class Solution {
    public boolean isHappy(int n) {
        Set set = new HashSet();

        while(n != 1 && !set.contains(n)){
            set.add(n);
            n = getNum(n);
        }

        return n == 1;
    }
    private int getNum(int n){
        int res = 0;
        while(n > 0){
            int tmp = n % 10;
            res += tmp*tmp;
            n /= 10;
        }
        return res;
    }
}

1. 两数之和

  • 暴力求解,yyds!

  • 对java中map的基本操作不熟悉。
    Map 接口的常用实现类:HashMap、LinkedHashMap、TreeMap 和Properties。其中,HashMap 是 Map 接口使用频率最高的实现类。
    • 添加、修改操作:
    – Object put(Object key,Object value):将指定 key-value 添加到(或修改)当前 map 对象中
    – void putAll(Map m):将 m 中的所有 key-value 对存放到当前 map 中
    • 删除操作:
    – Object remove(Object key):移除指定 key 的 key-value 对,并返回 value
    – void clear():清空当前 map 中的所有数据
    • 元素查询的操作:
    – Object get(Object key):获取指定 key 对应的 value
    – boolean containsKey(Object key):是否包含指定的 key
    – boolean containsValue(Object value):是否包含指定的 value
    – int size():返回 map 中 key-value 对的个数
    – boolean isEmpty():判断当前 map 是否为空
    – boolean equals(Object obj):判断当前 map 和参数对象 obj 是否相等
    • 元视图操作的方法:
    – Set keySet():返回所有 key 构成的 Set 集合
    – Collection values():返回所有 value 构成的 Collection 集合
    – Set entrySet():返回所有 key-value 对构成的 Set 集合

  • 一个难点

    • map中的key存每一位的值,value存其的位置
    • 使用余数获取各位的数值,使用商对数据做递减。
    • 如何判定循环结束的条件?
    • 无限循环,那么也就是说求和的过程中,sum会重复出现
class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer,Integer> map = new HashMap();
        map.put(nums[0] , 0);
        int differ = -1;
        for(int i = 1; i < nums.length; i++){
            differ = target - nums[i];
            if(map.containsKey(differ)){
                return new int[]{map.get(differ),i};
            }
            map.put(nums[i],i);
        }
        return new int[2];
    } 
}

160. 链表相交

  • 思路:一定要将两个链表的尾部对齐,因为如果相交的话,一定有共同的尾部。
  • 先确认两个链表的长度!
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode curA = headA;
        ListNode curB = headB;
        int num1 = 0;
        int num2 = 0;
        int count;
        int min = 0;

        while(curA != null){
            curA = curA.next;
            num1++;
        }
        while(curB != null){
            curB = curB.next;
            num2++;
        }
        // 重新指定头,并将长链表的头移动到短链表头的位置
        curA = headA;
        curB = headB;
        if(num1 >= num2){
            count = num1 - num2;
            while(count-- > 0){
                curA = curA.next;
            }
        }
        else{
            count = num2 - num1;
            while(count-- > 0){
                curB = curB.next;
            }
        }
        min = Math.min(num1,num2);
        while(min-- > 0){
            if(curA == curB){
                return curA;
            }
            curA = curA.next;
            curB = curB.next;
        }
        return null;

    }
}

学习时间:

  • 上午三小时,下午整理文档半小时
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值