LeetCode刷题---817. 链表组件(哈希表)

请添加图片描述

  • 💌 所属专栏:【LeetCode题解(持续更新中)】

  • 😀 作  者:我是夜阑的狗🐶

  • 🚀 个人简介:一个正在努力学技术的码仔,专注基础和实战分享 ,欢迎咨询!

  • 💖 欢迎大家:这里是CSDN,我总结知识的地方,喜欢的话请三连,有问题请私信 😘 😘 😘

您的点赞、关注、收藏、评论,是对我最大的激励和支持!!!🤩 🤩 🤩


前言

  大家好,又见面了,我是夜阑的狗,本文是专栏【LeetCode题解】专栏的第6篇文章,主要讲解是LeetCode817. 链表组件(哈希表)。
  专栏地址:【LeetCode题解(持续更新中)】, 此专栏是我是夜阑的狗对LeetCode问题的讲解,希望能够加深自己的印象,以及帮助到其他的小伙伴😉😉。
  如果文章有什么需要改进的地方还请大佬不吝赐教👏👏。


一、编程题:75. 颜色分类(双指针,循环不变量)

1.题目描述

  给定链表头结点 head,该链表上的每个结点都有一个 唯一的整型值 。同时给定列表 nums,该列表是上述链表中整型值的一个子集。返回列表 nums 中组件的个数,这里对组件的定义为:链表中一段最长连续结点的值(该值必须在列表 nums 中)构成的集合。LeetCode题目链接。

2.示例1:

输入: head = [0,1,2,3], nums = [0,1,3]
输出: 2
解释: 链表中,0 和 1 是相连接的,且 nums 中不包含 2,所以 [0, 1] 是 nums 的一个组件,同理 [3] 也是一个组件,故返回 2。

3.示例2:

输入:输入: head = [0,1,2,3,4], nums = [0,3,1,4]
输出: 2
解释: 链表中,0 和 1 是相连接的,3 和 4 是相连接的,所以 [0, 1] 和 [3, 4] 是两个组件,故返回 2。

4.提示:

  • 链表中节点数为n
  • 1 <= n <= 104
  • 0 <= Node.val < n
  • Node.val 中所有值 不同
  • 1 <= nums.length <= n
  • 0 <= nums[i] < n
  • nums 中所有值 不同

二、解题思路

这里一定要注意题干的要求,链表跟数组都是无序的(本人被坑过)。

1.思路

解决方法1(个人想法):

  • Step1.用while循环遍历链表head,再根据head.val来判定是否存在nums数组中;
  • Step2.用循环来判定head.val是否在nums中,当head.val == nums[i]时,则将head.val置为-1表示存在,并结束循环;
  • Step3.处理完链表之后,再对链表中的-1结点进行计算,这里设置flag=0(当flag为0时,表示该结点的数据再nums里是不存在的,反之为1表示存在);
  • Step4.当head.val != -1且flag == 1时,说明该结点之前的数为一个组件;当head.val == -1时,则flag=1,这里要考虑到当前结点为边界结点,组件数count要加1;

解决方法2(哈希表):
在前面的基础上引入HashSet集合,加快查询的速度,这里不用ArraysList的原因是hashSet查询比较快。

  • Step1.创建HashSet集合来存储数组;
  • Step2.(循环1)遍历链表head,当head.val存在于set中时,则进入循环2判断下一个结点是否存在,当下一个结点不存在时,结束循环2,组件数count+1;反之当head.va不l存在于set中则指向下一个结点即可;

三、代码实现

。每个代码块都写了注释,方便理解,代码还可以改进;
代码如下(示例):
解法一:

class Solution {
    public int numComponents(ListNode head, int[] nums) {
        //方法一
        int count = 0, flag = 0; //组件个数
        ListNode left = head;
        ListNode result = head;
        
        while(left != null){
            for(int i = 0; i < nums.length; i++){
                if(nums[i] == left.val){
                    left.val = -1;
                    break;
                }
            }
            left = left.next;
        }

        while(result != null){
            if(result.val != -1 && flag == 1){
                // System.out.println(result.val);
                count++; flag = 0;
            }else if(result.val == -1){
                // System.out.println("=>"+result.val);
                flag = 1;
                if(result.next == null) count++;
            }
            result = result.next;
        }
        return count;
    }
}

解法二:

class Solution {
    public int numComponents(ListNode head, int[] nums) {
        //方法二
        int count = 0;
        HashSet<Integer> set = new HashSet<>();
        for(int number : nums) set.add(number);

        while (head != null){
            if(set.contains(head.val)){
                head = head.next; //这里可以减少一次不必要的循环
                while(head != null && set.contains(head.val)) head = head.next;
                count++;
            }else{ 
                head = head.next;
            }
            // 遍历链表:只有当前节点元素值在nums中且当前节点下一个节点值不在nums中时,才能作为1个独立组件
            // if(set.contains(head.val) && (head.next == null || !set.contains(head.next.val))) count++;
            // head = head.next;
        }
        return count;
    }
}

提交结果:
在这里插入图片描述


总结

以上就是今天要讲的内容,一开始做题的时候,刚开始写的时候,没有想到用hashSet来加快查询速度,于是用了两个while,搞得非常冗余,思路上也有待提升,看了三叶姐代码之后,发现可以用hashSet来加速判断,也感受到了三叶姐思路的清晰感,自己写的时候都是边写边错边改,所以就赶紧记录一下这个方法,开阔一下思路。

感谢观看,如果有帮助到你,请给题解点个赞和收藏,让更多的人看到。🌹 🌹 🌹

也欢迎你,关注我。👍 👍 👍

原创不易,还希望各位大佬支持一下,你们的点赞、收藏和留言对我真的很重要!!!💕 💕 💕 最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!

更多专栏订阅:



订阅更多,你们将会看到更多的优质内容!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是夜阑的狗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值