[leetcode-链表]817. Linked List Components

We are given head, the head node of a linked list containing unique integer values.

We are also given the list G, a subset of the values in the linked list.

Return the number of connected components in G, where two values are connected if they appear consecutively in the linked list.

我们给出了一个包含唯一整数值的链表的头节点。

我们也给出了链表G,链表中的值的子集。

返回G中连接的组件的数量,如果它们在链表中连续出现,则连接两个值。

Example 1:

Input: 
head: 0->1->2->3
G = [0, 1, 3]
Output: 2
Explanation: 
0 and 1 are connected, so [0, 1] and [3] are the two connected components.

Example 2:

Input: 
head: 0->1->2->3->4
G = [0, 3, 1, 4]
Output: 2
Explanation: 
0 and 1 are connected, 3 and 4 are connected, so [0, 1] and [3, 4] are the two connected components.

Note:

  • If N is the length of the linked list given by head1 <= N <= 10000.
  • The value of each node in the linked list will be in the range [0, N - 1].
  • 1 <= G.length <= 10000.
  • G is a subset of all values in the linked list.

//====================方法1==========================================================

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
/*
    C 库函数 qsort 对数组进行排序
    void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*)) 
    base -- 指向要排序的数组的第一个元素的指针。
    nitems -- 由 base 指向的数组中元素的个数。
    size -- 数组中每个元素的大小,以字节为单位。
    compar -- 用来比较两个元素的函数。
*/
int cmp(const void* a,const void* b){
    return *(int*)a-*(int*)b;
}

//折半查找
int bisearch(int *nums, int target, int size) {
    int left = 0, right = size-1, mid;
    
    while (left <= right) 
    {
        mid = left + (right - left) / 2;
        
        if (nums[mid] < target) 
            left = mid + 1;
        else if(nums[mid] > target)
            right = mid-1;
        else
            return 1;
    }
    
    return 0;
}

int numComponents(struct ListNode* head, int* G, int GSize) {
    if(head==NULL)
        return 0;
    
    //对子集进行排序
    qsort(G, GSize, sizeof(int), cmp);
    
    struct ListNode* pcur=head;
    int num=0;
    
    //遍历链表
    while(pcur)
    {
        //在子集中查找结点元素
        if(bisearch(G, pcur->val, GSize))
        {
            
            num++; //如果查到元素则子链表个数加1
            pcur=pcur->next; //链表指针指向下一个
            
            //在后续链表结点中继续查找,看是否在这个子集中
            while(pcur && bisearch(G, pcur->val, GSize))
            {
                pcur=pcur->next;
            }
        }
        else //如果子集中查不到该结点,则链表前进到下一个结点
        {
            pcur=pcur->next;
        }
    }
    
    return num;
}
//=============================方法2===============================================

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

//由唯一结点的特性,以链表结点的数值为索引,设置一个大数组用于存储,模拟hash table
#define TBL_SIZE 10001
static char val_cnt_tbl[TBL_SIZE];
static inline void val_cnt_tbl_reset(void)
{
    memset(val_cnt_tbl, 0, sizeof(val_cnt_tbl));    
}
static inline int val_cnt_tbl_get(int val)
{  
    return  (int)val_cnt_tbl[val];    
}
static inline void val_cnt_tbl_inc(int val)
{
    val_cnt_tbl[val]++;    
}
static void val_cnt_tbl_init(int* G, int size)
{   
    while (size-- > 0) 
    {
        val_cnt_tbl_inc(*G);
        G++;
    }    
}

#define STA_NONE  0
#define STA_CONN  1

int numComponents(struct ListNode* head, int* G, int GSize) {
    if(head==NULL)
        return 0;
    
    int num=0;
    int sta = STA_NONE;
    
    //构建table
    val_cnt_tbl_reset();
    //初始化table
    val_cnt_tbl_init(G, GSize);
        
    struct ListNode* pcur=head;
    
    //遍历链表
    while(pcur)
    {
        //如果结点在table中存在
        if(val_cnt_tbl_get(pcur->val))
        {
            //当前状态为空状态,则子链表个数加1;如果已在子链表中,则无需增加计数
            if(sta==STA_NONE)
            {
                num++;
                sta=STA_CONN;
            }
        }
        else //如果结点在table中不存在,设置当前状态为空
        {
            sta=STA_NONE;
        }
        
        pcur=pcur->next;
    }
    
    return num;
}
 

猜你喜欢

转载自blog.csdn.net/qq_20398345/article/details/81098627