1. 程式人生 > >[LeetCode] Linked List Components 連結串列元件

[LeetCode] 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.

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.

這道題給了我們一個連結串列,又給了我們一個結點值陣列,裡面不一定包括了連結串列中所有的結點值。讓我們返回結點值陣列中有多少個相連的元件,因為缺失的結點值會將原連結串列斷開,實際上就是讓我們求有多少個相連的子連結串列,題目中給的例子很好的說明題意。這道題並不需要什麼特別高深的技巧,難懂的演算法,直接按題目的要求來找就可以了。首先,為了快速的在結點值陣列中查詢某個結點值是否存在,我們可以將所有的結點值放到一個HashSet中,這樣我們就能在常數級的時間複雜度中查詢。然後我們就可以來遍歷連結串列了,對於遍歷到的每個結點值,我們只有兩種情況,在或者不在HashSet中。不在HashSet中的情況比較好辦,說明此時斷開了,而在HashSet中的結點,有可能是該連續子連結串列的起始點,或者是中間的某個點,而我們的計數器對該子連結串列只能自增1,所以我們需要想辦法來hanlde這種情況。博主最先想到的辦法是先處理不在HashSet中的結點,處理方法就是直接跳到下一個結點。那麼對於在HashSet中的結點,我們首先將計數器res自增1,然後再來個迴圈,將之後所有在集合中的結點都遍歷完,這樣才不會對同一個子連結串列多次增加計數器,參見程式碼如下:

解法一:

class Solution {
public:
    int numComponents(ListNode* head, vector<int>& G) {
        int res = 0;
        unordered_set<int> nodeSet(G.begin(), G.end());
        while (head) {
            if (!nodeSet.count(head->val)) {
                head = head->next;
                continue;
            }
            ++res;
            while (head && nodeSet.count(head->val)) {
                head = head->next;
            }
        }
        return res;
    }
};

我們可以稍稍修改程式碼,使其更加簡潔,我們在遍歷的時候進行判斷,如果當前結點在集合中,並且當前結點是尾結點或者下一個結點不在集合中的時候,我們讓計數器自增1,通過這種操作,我們不會多加也不會漏加計數器,參見程式碼如下:

解法二:

class Solution {
public:
    int numComponents(ListNode* head, vector<int>& G) {
        int res = 0;
        unordered_set<int> nodeSet(G.begin(), G.end());
        while (head) {
            if (nodeSet.count(head->val) && (!head->next || !nodeSet.count(head->next->val))) {
                ++res;
            }
            head = head->next;
        }
        return res;
    }
};

參考資料: