LeetCode817链表组件

LeetCode817链表组件

题目:

给定一个链表(链表结点包含一个整型值)的头结点 head。

同时给定列表 G,该列表是上述链表中整型值的一个子集。

返回列表 G 中组件的个数,这里对组件的定义为:链表中一段最长连续结点的值(该值必须在列表 G 中)构成的集合。

示例:

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

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

注意:
  • 如果 N 是给定链表 head 的长度,1 <= N <= 10000。

  • 链表中每个结点的值所在范围为 [0, N - 1]。
    1 <= G.length <= 10000

  • G 是链表中所有结点的值的一个子集.

代码块:
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

int numComponents(struct ListNode* head, int* G, int GSize)
{

}
题目属于什么类型?
  • 链表
  • 数组
题目主要部分是什么?
  • 一个给定的链表head,head指向第一个结点,本题中没有头结点
  • 一个给定的数组GG是链表的子集
  • 求数组G中的组件个数 是组件个数不是最长组件的长度
  • 组件:链表中一段最长连续结点的值(该值必须在列表 G 中)构成的集合。
从已知量可以得到什么东西吗?

(初始状态)

struct ListNode 
{
     int val;
     struct ListNode *next;
 };
  • 链表结点包含一个整型值用val表示
  • 给定链表长度N为[1,10000],且val的取值范围为[1,N-1]
  • G是链表的一个子集
问题本身是什么

(要解决的问题)

  • 返回G中包含链表组件的个数num
  • G中包含链表组件的个数num
  • 链表组件的个数num
  • 个数num
什么东西可以得到什么答案呢?

(目标状态)

  • 找到链表的每个组件
解题思路
  • 遍历链表,对于链表head的每一个结点p,判断p->val是否在G中存在,如果G中存在p->val,那么我们需要判断p->next是否存在于G中,如果p->next不在链表head中,我们就找到了一个组件,将答案num+1。反之继续遍历链表,知道遍历到p->next不在链表head中。
  • 找到一个组件后,重复上述过程,直到遍历到链表结尾,找到所有组件,得到最终答案num
具体解题步骤
  • 判断传入函数numComponents中的head链表和数组G是否为空,如果二者中有一个为空,则num为0。
  • 传建一个长度为10000(也可以优化为max(给定链表),降低空间复杂度)的数组Bool,赋初值0。
  • G中的值对应的对应的Bool的下标的值置为1,这样,就可以通过判断数组Bool的值是否为0来判断链表head的元素是否在数组G中。
  • 遍历链表,寻找到一个组件后,num自增一次。直到遍历到链表结尾,返回num
代码实现
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 * 注意:题目返回值是列表G中的组件个数,不是最长组件长度
 */
int numComponents(struct ListNode* head, int* G, int GSize)
{
    if(head==NULL || GSize==0)
        return 0;

    struct ListNode* p;
    p = head;//head表示第一个结点,不是头结点
    int Bool[10000] = {0};//可以优化为Bool[max(给定链表)],减少申请的空间数目
    int i,num=0, flag;

    for(i=0; i<GSize; i++)
        Bool[G[i]]++;
    
    while(p!=NULL)
    {
        flag = 0;
        while(p!=NULL && Bool[p->val]!=0)//需要先判断p是否为空,然后再判断链表的值是否在G中,否则当p为空时,找不到p->val,程序会报错
        {
            p = p->next;
            flag = 1;
        }

        if(flag == 1)//链表添加一个判断标志,当flag==1时,表示执行过while循环,反之表示没有执行while循环,即链表的值没出现在G中,或者链表已经遍历到结尾,只有当flag==1时num才应该自增。
            num++;
        
        if(p != NULL)//不执行while循环时,p也需要向后移动,并且需要判断while不为空
            p = p->next;
    }
    return num;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值