【每日一题】817.链表组件 2022/10/12

题目

链表组件

思路

初看题目似乎有点难理解,细看首先粗体字告诉我们链表内所有整型都是唯一的,第二点给的数组nums里面的数在链表内,所求就是nums里面的数放回链表内可以分成多少个连续的块。 比如:

linklist = [1,2,3,4,5]
nums = [1,2,4,5]

链表内12就是一块, 45就是一块,答案就是2,如果nums里面多了一个3,那么12345就是一块,答案就是1,并且答案与nums数组里面数字的顺序无关。

那么解题的思路就是,遍历整个链表,如果当前的数在nums数组中存在,并且链表的前一个数不在nums数组中则答案+1。这样就需要一个pre记录前一个链表值是否在nums数组中,当前值不在则给pre赋值为false,反之为true。这种思路的时间复杂度为O(n)。

然后是find的部分,因为看到给定整型的值的范围为

1 <= n <= 10000

 所以我第一时间想到了用桶来装nums数组,实现思路为

int busket[10001] = {0};
for (int i = 0; i < nums.size(); i ++) {
   busket[nums[i]] = 1;
}

然后遍历链表时只需要判断busket[val]是否为1就可以确定val是否在nums数组中了。这样空间复杂度为O(n)。

这样的思路看起来很合理,于是代码如下

class Solution {
public:
    int numComponents(ListNode* head, vector<int>& nums) {
        int busket[10001] = {0};
        for (int i = 0; i < nums.size(); i ++) {
            busket[nums[i]] = 1;
        }

        int ans = 0;
        bool pre = false;
        ListNode* node = head;
        while(node) {
            if(busket[node->val]) {
                if(!pre) ans ++;
                pre = true;
            } else {
                pre = false;
            }
            node = node -> next;
        }

        return ans;
    }
};

结果也十分顺利

然后看了看评论,可以使用集合来装nums数组,因为c++有set类所以也非常方便,并且在适用于整型较大的情况,于是小改一下代码

class Solution {
public:
    int numComponents(ListNode* head, vector<int>& nums) {
        set<int> num;
        for (int i = 0; i < nums.size(); i ++) {
            num.insert(nums[i]);
        }

        int ans = 0;
        bool pre = false;
        ListNode* node = head;
        while(node) {
            if(num.count(node->val)) {
                if(!pre) ans ++;
                pre = true;
            } else {
                pre = false;
            }
            node = node -> next;
        }

        return ans;
    }
};

顺便复习一下set的用法,不过用这种方法时间和内存都稍大一些,在这题中还是前一种方法更适合一些。

反思

1、这道题总体来说难度不算很大,主要是要理解题目的意思,刚阅读时会想考虑nums和链表中数的顺序会不会对结果造成影响,但实际上不会。如果题目改成链表和nums数组中有多少个相同的连续块那么

linklist = [1,2,3,4,5]
nums = [5,4,3,1,2]

这种情况下[1,2]就是1块,[3],[4],[5]都单独为一块,答案为4,解题思路应该就会变成搜索,时间复杂度就变成O(n^{2}) (也许有更好的方法),代码就会相对复杂一些。

2、在遇到整型数字较小的,涉及排序查找的情况,可以多思考使用类似桶排序的思路。

3、vector大小是size不是length。

4、不同容器的插入方法不要记混,比如set插入用insert不是push。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

今夜大疯小宇

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

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

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

打赏作者

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

抵扣说明:

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

余额充值