Amber-leedcode-java-代码随想录打卡第六天 | 242.有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和

发布时间:2024年01月22日

:)前言

短短续续的总算补上了,希望自己坚持下去。大家如果有疑问在评论区多多讨论呀~

242.有效的字母异位词

1.思路笔记:

总体来说较为简单,其中数组的取值比较巧妙,需要记住

2.代码

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 i = 0;i < 26;i++){
             if (record[i] != 0){
                 return false;
             }
    }
    return true;
    }
}

?349. 两个数组的交集?

1.要点:

1.问题一:

对于我来说,如何建立一个正确的HashSet和HashMap是比较难的,两者的区别如下:

1.HashMap
  • 定义HashMap 是一个存储键值对的集合。每个键映射到一个值。
  • 特点:键是唯一的,但是它们的值可以重复。如果你尝试插入一个已经存在的键,它的值将被新值替换。
  • 用途:适用于需要快速查找、插入和删除键值对的场景。
2.HashSet
  • 定义HashSet 是一个只存储对象的集合,它不存储键值对
  • 特点:它确保集合中的元素不重复(唯一性)。HashSet不保证元素的存储顺序,也不保证顺序随时间的改变保持不变。
  • 用途:适用于需要维护一组唯一元素的场景,不关心元素的顺序。
2.问题二:

其中,关于为什么只能用integer来初始化hashset而不可以用int的类型,我也比较疑惑,在最开始的时候我也写错了,c(chatgpt)老师给出的解析如下:

要将 HashSet<int> 类型转换为 int 类型的数组,你可以使用 stream 方法和 mapToInt 方法来实现。但首先,需要注意的是,在Java中,HashSet 不能直接存储基本数据类型如 int,而是存储它们的包装类,例如 Integer。因此,正确的声明应该是 HashSet<Integer> 而不是 HashSet<int>

--------------------------------------------------------------------------------------------------------------------------------

1.int 和 Integer 的区别
  • intint 是Java中的基本数据类型,用于表示整数值。它不是一个对象,占用的内存更少,效率更高。

  • IntegerIntegerint 的包装类,属于Java的类库。作为一个类,Integer 提供了一些有用的类方法,例如将字符串转换为整数,以及 int 与其他基本类型之间的转换等。Integer 也可以用于泛型,如在集合类中。

2.为什么 int 和 Integer 的数组不一样
  • int[] 是基本数据类型 int 的数组,直接存储值。

  • Integer[] 是对象数组,存储的是指向 Integer 对象的引用。

由于 Integer 是对象,因此 Integer[] 可以存储 null 值,而 int[] 不能。此外,在处理集合类如 ArrayListHashSet 时,由于泛型不支持基本数据类型,因此需要使用它们的包装类,如 Integer

3.问题三:判断一个哈希表里面是否包括一个值的函数:
boolean containsApple = set.contains("苹果"); // 返回true
4.如何转换hashset到array[int]类型

其实我还是不太理解这个代码的含义。。有大佬可以讲讲hh

Set<Integer> result = new HashSet<>();
int[] array = result.stream().mapToInt(i -> i).toArray();
1.c老师的回答第一版

c老师的解释,感觉很清楚,但我还是不是很理解:

int[] array = result.stream().mapToInt(i -> i).toArray();。这行代码是Java 8及以上版本中的一个示例,展示了如何将一个HashSet<Integer>转换为一个基本类型数组int[]。下面我将逐部分进行解释:

  1. result.stream()

    • result 是一个 HashSet<Integer> 类型的集合。
    • .stream() 方法将这个集合转换成一个流(Stream)。在Java中,流是一系列数据项的序列,它支持多种操作,可以对这些数据项进行处理。
  2. .mapToInt(i -> i)

    • .mapToInt 是一个中间操作,它接受一个函数作为参数,并将流中的每个元素应用这个函数。
    • 在这个例子中,i -> i 是一个lambda表达式,它接收一个参数 i 并直接返回它。这里的 i 代表流中的每一个 Integer 元素。
    • .mapToInt 方法的作用是将每个 Integer 元素转换为 int 类型。这里发生的是自动拆箱操作,即将 Integer 对象转换为基本数据类型 int
  3. .toArray()

    • 这是一个终端操作,它将流处理的结果收集起来,并返回一个数组。
    • 在这个例子中,.toArray() 收集所有经过 mapToInt 处理的 int 值,并将它们组成一个数组。
    • 结果是一个 int[] 类型的数组,这个数组包含了原始 HashSet<Integer> 集合中所有元素的 int 值。

综上所述,这行代码的整体作用是将一个 HashSet<Integer> 集合中的所有 Integer 元素转换为一个基本数据类型为 int 的数组。这种转换在Java 8及以上版本中,通过流(Stream)API和lambda表达式实现起来非常简洁和直观。

2.c老师的回答第二版

----------------------------------------------------------------------???????--------------???????--------------???????--------------???????--------------???????

更新:

chat老师的另一个回答,我感觉更好:

在Java中,`stream` 是一个非常强大的工具,它用于对数据集合(hashset是数据集合)进行各种操作,比如筛选、转换、聚合等。`stream` 可以看作是一种高级迭代器,允许你以声明式的方式处理数据集合。

让我们通过一个故事来理解 `stream`:

想象你是一家餐厅的厨师,你手里有一个装满蔬菜的篮子(这个篮子就像一个集合)。你的任务是准备一道蔬菜沙拉。在这个过程中,你需要对篮子里的蔬菜进行一系列的操作,比如清洗、切片、挑选等。

1. **清洗蔬菜(Filtering):** 首先,你需要清洗所有的蔬菜。这就像使用 `stream` 的 `filter` 方法,它允许你从集合中筛选出符合特定条件的元素。

2. **切片(Mapping):** 清洗后,你需要将蔬菜切成片。这就像 `map` 操作,它允许你将集合中的每个元素转换成另一种形式。

3. **挑选(Collecting):** 最后,你可能只需要一些特定的蔬菜片来制作沙拉。这就像 `collect` 操作,它允许你将 `stream` 中的元素收集到新的集合中。

现在,关于你提到的代码:`int[] array = result.stream().mapToInt(i -> i).toArray();`,这段代码中:

- `result.stream()` 将 `result` 集合转换成了一个 `stream`。
- `mapToInt(i -> i)` 是一个 `map` 操作,它将 `stream` 中的每个元素转换成了 `int` 类型,但这里的 `i -> i` 实际上是一个恒等转换,即不对元素进行任何改变。
- `toArray()` 将 `stream` 中的元素收集到一个数组中。

这段代码实际上是将一个整数类型的集合(比如 `List<Integer>`)转换成了一个基本类型的数组 `int[]`。但考虑到 `mapToInt(i -> i)` 实际上没有对元素做任何转换,这里的 `mapToInt` 可以被认为是多余的。如果 `result` 已经是 `List<Integer>` 类型,这段代码可以被简化为 `int[] array = result.stream().mapToInt(Integer::intValue).toArray();`。

这种简化是因为 `Integer::intValue` 是一个方法引用,它会自动为每个 `Integer` 对象调用 `intValue()` 方法,将其转换为 `int` 类型,这是自动拆箱的一个例子。如果 `result` 是 `List<Integer>` 类型,这种简化是有效的,因为 `List<Integer>` 中的每个元素本质上已经是 `Integer` 对象,可以直接进行拆箱操作。

--------------???????--------------???????--------------???????--------------???????--------------???????--------------???????--------------???????--------------???????--------------????



2.精华笔记

3.Code

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {


        HashSet<Integer> result = new HashSet<Integer>();

        HashSet<Integer> hs = new HashSet<Integer>();

        for (int i = 0;i < nums1.length;i++){
            hs.add(nums1[i]);
        }

        for (int i = 0;i< nums2.length;i++){
            if (hs.contains(nums2[i])){
                result.add(nums2[i]);
            }
        }

        // Integer[] array = new Integer[result.size()];
        int[] array = result.stream().mapToInt(i -> i).toArray();

        return array;

    }
}

202. 快乐数

自己没看解析写出来了,很开心,嘻嘻。哈希表主要应用于是否出现过一样的数值,如果出现说明有循环,肯定不是快乐数。

class Solution {
    public boolean isHappy(int n) {
        HashSet<Integer> result = new HashSet<Integer>();
        while (true){
        ArrayList<Integer> split = new ArrayList<Integer>();
        int sum = 0;
        if (n < 10){
            split.add(n);
        }else if (n >= 10){
            while (true){
                int result_first = n/10;
                int result_last = n%10;
                if (result_first >= 10){
                    split.add(result_last);
                }else{
                    split.add(result_last);
                    split.add(result_first);
                    break;
                }
                n=result_first;
            }
        }
        
    for (int i = 0; i < split.size(); i++) {
         sum = sum + split.get(i) * split.get(i);
    }
    if (sum == 1){
        return true;
    }else if (result.contains(sum)){
        return false;
    }
    result.add(sum);
    n=sum;
    }

    }
}

1. 两数之和

比较顺利

1.思考点

代码随想录的这里比较需要思考:

本题其实有四个重点:

  • 为什么会想到用哈希表
  • 哈希表为什么用map
  • 本题map是用来存什么的
  • map中的key和value用来存什么的

首先我再强调一下?什么时候使用哈希法,当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。

本题呢,我就需要一个集合来存放我们遍历过的元素,然后在遍历数组的时候去询问这个集合,某元素是否遍历过,也就是 是否出现在这个集合。

那么我们就应该想到使用哈希法了。

因为本题,我们不仅要知道元素有没有遍历过,还要知道这个元素对应的下标,需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map正合适

2.遇到的一些code问题:

HashMap中是否包含一个key的函数,不是只有contains了:

result.containsKey(rest)

HashMap中放入一个key和value,不是add了,是put:

 result.put(nums[i],i);

3.Code

class Solution {
    public int[] twoSum(int[] nums, int target) {

        HashMap<Integer,Integer> result = new HashMap<Integer,Integer>();
        int[] result_array = new int[2];

       for (int i=0;i < nums.length;i++){
           int rest = target - nums[i];
           if (result.containsKey(rest)){
               result_array[0] = i;
               result_array[1] = result.get(rest);
               return result_array;
           }else{
               result.put(nums[i],i);
           }
       }
    return result_array;
    }
}

总结:

  1. 状态:完结
  2. 学习三小时左右
  3. 困难:主要是在代码实现上遇到的困难,比如hash的创建使用等等。
  4. 待解决问题:stream是啥?- > 已解决
  5. 今日收获:很多。。不一一列出了
  6. 来源:代码随想录
文章来源:https://blog.csdn.net/avery66666/article/details/135615018
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。