代码随想录训练营第六天|LeetCode242(有效的字母异位词)、349(两个数组的交集)、202(快乐数)、1(两数之和)

LeetCode 242 有效的字母异位词

题目链接:LeetCode.242

  1. 解题思路

  • 本题目代码随想录采用了“哈希发”来解题,所谓使用了哈希法,其实是因为作者用了数组,但是仅仅用了数组就说采用了哈希法,本人感觉有点过于牵强,因为并没有用到哈希函数。

  • 作者的思路比较巧妙,下面我将复述一下解题步骤,顺便也可以检验一下自己是否真的理解了。

  • 首先,小写英文字母一共有26个,所以我们定义一个名叫record的数组,大小为26。那么如何比较两个词语是否具有完全一样的字母呢?作者的思路是统计双方各字母出现的频次,如果两个词语的频次相同,那么我们就可以确定两个词语是字母完全一样的异构词了。

  • 那么如何统计两个词语的频次呢?这里就是本题比较巧妙的构思了,我们知道26个英文字母的ASCII值是26个连续的值,那么我们设定首字母a为基准值,其余每个字母减去'a',都会得到唯一一个值,代表他们本身。比如,字母'e'减去'a'得到的值是4,这就是字母e本身独特的索引。

  • 接下来,就需要将每个字母出现的次数存储在上面定义的record数组里,如上,我们得到了'e'的索引值为4,那么record[4]处存储的数据就代表了有关'e'的信息。此处数字为几,就说明此字母在单词中出现了几次。

  • 之后我们用这个已经更新过数值的数组record再去记录另外一个单词中字母出现的次数,只不过这次和上面不同之处在于,这次只要某个字母出现了,我们就将数值减去1。比如,统计完第一个单词后,字母'e'处的数据为3,说明第一个单词里有三个字母e;如果统计完第二个单词后,e处的数据变为了2,那么说明第二个单词里有一个e,以此推理下去,只要第二个单词里e处的值不为0,就可以说明两个单词里'e'的个数不一致。

  • 所以,最后我们只要统计最后的数组是否所有数据全为0,如果是,就说明两个单词是有完全一样的字母所构成。

2.实例代码(Java)

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;
    }
}

代码说明:

  • int[] record = new int[26];此代码里用'[]'首先声明了一个数组,然后用‘new’操作符创建了数组对象。‘record’是我们创建的数组的名字。

  • charAt(int index):返回字符串中指定索引位置的字符。

  • for (int count: record) {

if (count != 0) {

return false;

}

}

此处使用了Java 中的增强的 for 循环语法,也被称为 foreach 循环。增强的 for 循环语法可以遍历一个数组或一个集合中的所有元素,具体格式为:

for (元素类型 元素变量 : 遍历对象) {

// 循环体

}

在这里,元素类型是指遍历对象中元素的类型,元素变量是指在循环中引用每个元素的变量名,遍历对象则是指需要遍历的数组或集合。在每次迭代中,元素变量会被自动赋值为遍历对象中的下一个元素,因此可以直接在循环体中使用该变量进行处理。

LeetCode 349 两个数组的交集

题目链接:349.两个数组的交集

  1. 解题知识准备

  • Set是一种数据结构,在使用哈希法解决问题时,我们一般会选择如下三种数据结构:数组、Set(集合)、Map(映射)。

  • Java里使用Set时,主要有两种,第一种是HashSet类,特点是集合里的元素唯一,可以无序,也可以含有空元素;另一种是TreeSet类,特点是 元素唯一,有序,不能含有空元素。

  • 如何在Java里实现一个集合呢?

以‘HashSet‘为例:Set<String> myset = new HashSet<>();

  1. 解题思路

  • 此题有一个要求就是去重,我们首先将数组1中的数据重新写入到HashSet集合1中,利用Set集合数据的唯一性,对数组1中相同数据进行去重;

  • 然后我们遍历数组2,如果集合1中含有和数组2中相同的数据,那么我们就写入集合2,此时如果数组2中含有重复的数据,就算写入了集合2,也会被去重。

  • 最后我们要将得到的集合2重新写入一个新的数组中,得到输出结果。

  • 注意一点,开始前要先判断两个数组是否为空,只要有一个数组为空,就得返回空数组。

  1. 代码示例(Java)

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        if (nums1 == null || nums2 == null){
            return new int[0];
        }
        Set<Integer> set1 = new HashSet<>();
        Set<Integer> resSet = new HashSet<>();
        for (int a : nums1){
            set1.add(a);
        }
        for (int b : nums2){
            if (set1.contains(b)){
                resSet.add(b);
            }
        }
        int[] res = new int[resSet.size()];
        int c = 0;
        for (int d : resSet){
            res[c++] = d;
        }
        return res;
    }
}

代码说明

  • Set<Integer> set1 = new HashSet<>(); 这段代码声明了一个叫做set1的集合,集合里的元素都是整数,集合类型是HashSet类型。

  • for (int a : nums1);此处复习了上道题目的foreach,注意此处遍历的是数据,b代表将要遍历的nums2里的每一个数据。

LeetCode 202 快乐数

题目链接:202.快乐数

  1. 解题思路

  • 本题首先要积累一个知识点,就是求一个数,各个位上平方的和。思路是从个位上开始一一求解,先对数字n用10取余,%10,得到各位数字,之后除10,/10,抹除了个位数字,之后继续取余,得到百位的数字,以此类推。

  • 本题采用了和上道题一样的方法,采用集合来解题。这是因为求取快乐数有两种情况,一种就是求得了快乐数1,一种就是会陷入到循环里,比如你求得了一个数字为58,之后某次你又求出了58,这说明产生了循环,此原始数字不是快乐数。那么我们将每一次求得的结果都存入集合里,每一次都去判断求得的新数字是否在集合里存在,此种查找方式速度最快,这也是我们选择集合求取的原因。

  1. 代码示例

class Solution {
    public boolean isHappy(int n) {
        Set<Integer> a = new HashSet<>();
        while (n != 1 && !a.contains(n)){
            a.add(n);
            n = getNum(n);
        }
        return n == 1;
    }
    private int getNum(int n){
            int res = 0;
            while (n > 0){
                int temp = n % 10;
                res += temp * temp;
                n = n / 10;
            }
            return res;
        }
}

代码说明:

  • 无。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值