Problem Statement

Brute Force [TLE]
class Solution:
def numberOfAlternatingGroups(self, colors: List[int], k: int) -> int:
left = 0
right = k - 1
N = len(colors)
res = 0
queue = deque([color for color in colors[:k]])
def isValid(q):
for i in range(len(q) - 1):
if q[i] == q[i + 1]:
return False
return True
while left < N:
if isValid(queue):
res += 1
queue.popleft()
right = (right + 1) % N
queue.append(colors[right])
left += 1
return res
Editorial
Approach 1: Expanding the Array & Sliding Window
class Solution:
def numberOfAlternatingGroups(self, colors: List[int], k: int) -> int:
# Extend the array to handle circular sequences
for i in range(k - 1):
colors.append(colors[i])
length = len(colors)
result = 0
# Initialize the bounds of the sliding window
left = 0
right = 1
while right < length:
# Check if the current color is the same as the last one
if colors[right] == colors[right - 1]:
# Pattern breaks, reset window from the current position
left = right
right += 1
continue
# Extend window
right += 1
# Skip counting sequence if its length is less than k
if right - left < k:
continue
# Record a valid sequence and shrink window from the left to search for more
result += 1
left += 1
return result
Approach 2: Two Passes
class Solution:
def numberOfAlternatingGroups(self, colors, k):
length = len(colors)
result = 0
# Tracks the length of the current alternating sequence
alternating_elements_count = 1
last_color = colors[0]
# First pass through the array
for index in range(1, length):
# Check if the current color is the same as the last one
if colors[index] == last_color:
# Pattern breaks, reset sequence length
alternating_elements_count = 1
last_color = colors[index]
continue
# Sequence can be extended
alternating_elements_count += 1
# If sequence length reaches at least k, count it
if alternating_elements_count >= k:
result += 1
last_color = colors[index]
# Wrap around to the first k - 1 elements
for index in range(k - 1):
# Pattern breaks. Since there are less than k elements remaining,
# no more sequences can be formed
if colors[index] == last_color:
break
# Extend the pattern
alternating_elements_count += 1
# Record a new alternating sequence
if alternating_elements_count >= k:
result += 1
last_color = colors[index]
return result
Approach 3: One Pass
class Solution:
def numberOfAlternatingGroups(self, colors: List[int], k: int) -> int:
length = len(colors)
result = 0
alternating_elements_count = 1 # Length of current alternating sequence
last_color = colors[0] # Previous color
# Loop through array with circular traversal
for i in range(1, length + k - 1):
index = i % length # Wrap around using modulo
# Check if current color is the same as the last color
if colors[index] == last_color:
# Pattern breaks, reset sequence length
alternating_elements_count = 1
last_color = colors[index]
continue
# Extend sequence
alternating_elements_count += 1
# If sequence length reaches at least k, count it
if alternating_elements_count >= k:
result += 1
last_color = colors[index]
return result