817. 链表组件
题意
求链表中一段最长连续结点的值(值必须出现在列表G中,不要求顺序)构成的集合的个数;
解题思路
一开始还以为是要求顺序的,想说用递归来做,发现链表的值只是出现在列表中而已,因此判断链表中的值出现在列表中的次数(连续不算)即可,有点类似移动窗口的思路;
下面的实现是优化了几次,第一次是使用了dict,第二次是不需要统计哪些值不存在(大部分的时间消耗在in函数中,其实这部分没有必要进行判断,只需要判断出现的即可),第三版是最终的优化版本;
实现
class Solution(object):
def numComponents(self, head, G):
"""
执行用时 : 184 ms, 在Linked List Components的Python提交中击败了31.75% 的用户
内存消耗 : 18.8 MB, 在Linked List Components的Python提交中击败了100.00% 的用户
:type head: ListNode
:type G: List[int]
:rtype: int
"""
ans = 0
if not head:
return ans
G = set(G)
g_dict = {i: 1 for i in G}
while head:
# 如果不在列表中则一直移动,直到找到出现在G中的结点
while head and not g_dict.get(head.val, 0):
head = head.next
if head is None:
return ans
# 如果存在的话,则一直移动,直到找到没有出现在G中的结点
if g_dict.get(head.val, 0):
ans += 1
while head and g_dict.get(head.val, 0):
head = head.next
return ans
def numComponents2(self, head, G):
"""
执行用时 : 104 ms, 在Linked List Components的Python提交中击败了55.56% 的用户
内存消耗 : 18.7 MB, 在Linked List Components的Python提交中击败了100.00% 的用户
:type head: ListNode
:type G: List[int]
:rtype: int
"""
ans = 0
if not head:
return ans
G = set(G)
g_dict = {i: 1 for i in G}
while head:
# 如果在列表中则一直移动,直到找到没有出现在G中的结点
is_exist = False
while head and g_dict.get(head.val, 0):
is_exist = True
head = head.next
if is_exist:
ans += 1
else:
head = head.next
return ans
def numComponents3(self, head, G):
"""
执行用时 : 96 ms, 在Linked List Components的Python提交中击败了98.41% 的用户
内存消耗 : 18.8 MB, 在Linked List Components的Python提交中击败了100.00% 的用户
:type head: ListNode
:type G: List[int]
:rtype: int
"""
ans = 0
if not head:
return ans
G = set(G)
while head:
# 如果在列表中则一直移动,直到找到没有出现在G中的结点
is_exist = False
while head and head.val in G:
is_exist = True
head = head.next
if is_exist:
ans += 1
else:
head = head.next
return ans