Given an array nums of 0s and 1s and an integer k, return True if all 1's are at least k places away from each other, otherwise return False.
 
Example 1:

Input: nums = [1,0,0,0,1,0,0,1], k = 2
Output: true
Explanation: Each of the 1s are at least 2 places away from each other.

Example 2:

Input: nums = [1,0,0,1,0,1], k = 2
Output: false
Explanation: The second 1 and third 1 are only one apart from each other.
Example 3:
Input: nums = [1,1,1,1,1], k = 0
Output: true

Example 4:
Input: nums = [0,1,0,1], k = 1
Output: true

 
Constraints:

1 <= nums.length <= 10^5
0 <= k <= nums.length
nums[i] is 0 or 1

Difficulty: MEDIUM
Starter code: class Solution:
    def kLengthApart(self, nums: List[int], k: int) -> bool:


Solutions:
class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		if nums.count(0) == len(nums):
			return True
		idx = nums.index(1)
		ctr = 0
		for num in nums[idx + 1:]:
			if num == 1:
				if ctr < k:
					return False
				ctr = 0
			else:
				ctr += 1
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		if k == 0:
			return True
		N = len(nums)
		(past, curr) = (-1, 0)
		for curr in range(N):
			if nums[curr] == 1:
				if past < 0:
					past = curr
				elif curr - past > k:
					past = curr
				else:
					return False
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		s = -1
		n = len(nums)
		for i in range(n):
			if nums[i] == 1 and s == -1:
				s = i
			elif nums[i] == 1:
				interval = i - s - 1
				if interval < k:
					return False
				s = i
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		count = 0
		first = False
		for i in nums:
			if i == 1 and (not first):
				first = True
			elif i == 1 and first:
				if k <= count:
					count = 0
				else:
					return False
			else:
				count += 1
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		lis = []
		for i in range(len(nums)):
			if nums[i] == 1:
				lis.append(i)
		for i in range(1, len(lis)):
			if lis[i] - lis[i - 1] - 1 < k:
				return False
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		zCounter = k
		for n in nums:
			if n == 1:
				if zCounter < k:
					return False
				zCounter = 0
			else:
				zCounter += 1
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		p = 0
		count = k + 1
		while p < len(nums):
			if nums[p] == 1:
				if count <= k:
					return False
				else:
					count = 0
			count += 1
			p += 1
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		count = 0
		for i in range(len(nums)):
			if nums[i] == 1:
				if i >= 1:
					if count < k:
						return False
				count = 0
			else:
				count += 1
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		pos = []
		for i in range(len(nums)):
			if nums[i] == 1:
				pos.append(i)
		true = 0
		false = 0
		for j in range(len(pos) - 1):
			if pos[j + 1] - pos[j] <= k:
				return False
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		if 1 not in nums:
			return True
		num_place = nums.index(1)
		f_idx = nums.index(1) + 1
		for i in range(f_idx, len(nums)):
			if nums[i] == 1 and i - num_place < k + 1:
				return False
			elif nums[i] == 1 and i - num_place > k:
				num_place = i
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		next_one = 0
		previous_one = 0
		while next_one < len(nums) and nums[next_one] != 1:
			next_one += 1
		if next_one == len(nums):
			return True
		previous_one = next_one
		next_one += 1
		while next_one < len(nums):
			while next_one < len(nums) and nums[next_one] != 1:
				next_one += 1
			if next_one < len(nums) and next_one - previous_one - 1 < k:
				return False
			elif next_one < len(nums) and next_one - previous_one - 1 >= k:
				previous_one = next_one
			else:
				return True
			next_one += 1
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		zeros = 0
		i = 0
		while i < len(nums):
			if i == 0 and nums[i] == 1:
				i += 1
				continue
			if nums[i] == 1 and zeros < k:
				return False
				break
			elif nums[i] == 0:
				zeros += 1
				i += 1
			elif nums[i] == 1 and zeros >= k:
				zeros = 0
				i += 1
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		prev = 0
		while prev < len(nums) and nums[prev] == 0:
			prev += 1
		if prev == len(nums) or nums[prev] == 0:
			return True
		if k == 0:
			return True
		for i in range(prev + 1, len(nums)):
			if nums[i] == 1:
				if i - prev <= k:
					return False
				prev = i
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		if not k:
			return True
		pre_index = -1
		for (i, val) in enumerate(nums):
			if val:
				if pre_index != -1 and i - pre_index - 1 < k:
					return False
				pre_index = i
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		i = 0
		while i < len(nums) and nums[i] == 0:
			i += 1
		first = i
		for j in range(i + 1, len(nums)):
			if nums[j] == 0:
				continue
			else:
				second = j
				print((first, second))
				dis = second - first - 1
				if dis < k:
					return False
				first = second
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		position = -1
		for (index, item) in enumerate(nums):
			if item & 1:
				if index - position - 1 < k and position != -1:
					return False
				position = index
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		flag = 0
		start = None
		end = 0
		for i in range(len(nums)):
			if nums[i] == 1 and flag == 0:
				start = i
				flag = 1
			elif nums[i] == 1 and flag == 1:
				end = i
				dis = end - start
				start = i
				if dis <= k:
					return False
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		ind = 0
		for (i, num) in enumerate(nums):
			if not nums[ind] and num:
				ind = i
			if i != ind and num:
				if i - ind < k + 1:
					return False
				ind = i
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		locs = {}
		for i in range(len(nums)):
			if nums[i] == 1:
				locs[i] = True
		key = list(locs.keys())
		for i in range(len(key) - 1):
			if key[i + 1] - key[i] - 1 < k:
				return False
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		try:
			last = nums.index(1)
		except:
			return True
		for i in range(last + 1, len(nums)):
			if nums[i] == 1 and i - last <= k:
				return False
			elif nums[i] == 1:
				last = i
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		n = len(nums)
		prev = -1
		ans = []
		for i in range(n):
			if prev == -1:
				if nums[i] == 1:
					prev = i
			elif nums[i] == 1:
				ans.append(i - prev - 1)
				prev = i
		for i in ans:
			if i < k:
				return False
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		xs = [i for (i, n) in enumerate(nums) if n]
		return all((y - x > k for (x, y) in zip(xs, xs[1:])))


import numpy as np

class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		locs = np.where(np.array(nums) == 1)[0]
		return np.all(np.abs(np.diff(locs)) > k)


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		temp = 0
		increment = False
		one_checked = False
		for i in nums:
			if one_checked and i != 1:
				temp += 1
			print(temp, i)
			if i == 1:
				if one_checked and temp < k:
					return False
				temp = 0
				one_checked = True
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		import numpy as np
		ones = np.nonzero(nums)[0]
		if ones.size <= 1:
			return True
		diffs = np.diff(ones) - 1
		return k <= np.min(diffs)


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		(last_loc, curr_loc) = (-1, -1)
		for (i, n) in enumerate(nums):
			if n == 1:
				if last_loc == -1:
					last_loc = i
				elif curr_loc == -1:
					curr_loc = i
				curr_loc = i
				print((i, last_loc, curr_loc))
				if curr_loc - last_loc <= k and curr_loc != last_loc:
					return False
				last_loc = i
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		count = k
		for num in nums:
			if num == 1:
				if count < k:
					return False
				count = 0
			else:
				count += 1
		return True


from typing import List
import re

class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		matches = re.finditer('(1)', ''.join(map(str, nums)))
		indexes = tuple([getattr(el, 'span')()[0] for el in matches])
		for i in range(1, len(indexes)):
			diff = indexes[i] - indexes[i - 1]
			if diff <= k:
				return False
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		left = -1
		for i in range(len(nums)):
			if nums[i] == 1:
				if left == -1:
					left = i
				elif i - left - 1 < k:
					return False
				else:
					left = i
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		start = 0
		for ind in range(len(nums)):
			if nums[ind] == 1:
				start = ind
				break
		if start >= len(nums) - 1:
			return True
		minDist = float('inf')
		print(start)
		for i in range(start + 1, len(nums)):
			if nums[i] == 1:
				dist = i - start - 1
				if dist < minDist:
					minDist = dist
				start = i
		return minDist >= k


import numpy as np

class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		locs = [i for i in range(len(nums)) if nums[i] == 1]
		return all([locs[i + 1] - locs[i] > k for i in range(len(locs) - 1)])


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		ones = [-k - 1]
		for (i, num) in enumerate(nums):
			if num:
				if i - ones[-1] < k + 1:
					return False
				else:
					ones.append(i)
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		last = float('-inf')
		for (i, x) in enumerate(nums):
			if x == 1:
				if i - 1 - last < k:
					return False
				last = i
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		for idx in range(len(nums)):
			if nums[idx] == 1 and 1 in nums[idx + 1:idx + k + 1]:
				return False
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		if k == 0:
			return True
		while sum(nums) >= 2:
			temp = nums.index(1)
			nums[temp] = 0
			if nums.index(1) - temp <= k:
				return False
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		before = -k - 5
		for i in range(len(nums)):
			if nums[i] == 1:
				if i - before <= k:
					return False
				before = i
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		if k == 0:
			return True
		idx = [n for (n, x) in enumerate(nums) if x == 1]
		for i in range(1, len(idx)):
			print((idx[i], idx[i - 1]))
			if idx[i] - idx[i - 1] <= k:
				return False
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:

		def find(nums, *argc):
			try:
				return nums.index(*argc)
			except ValueError:
				return -1
		prev = find(nums, 1)
		while prev != -1:
			cur = find(nums, 1, prev + 1)
			if cur != -1 and cur - prev - 1 < k:
				return False
			prev = cur
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		pos = 0
		while pos < len(nums):
			try:
				pos = nums.index(1, pos)
				pos2 = nums.index(1, pos + 1)
			except:
				break
			if pos2 - pos - 1 < k:
				return False
			pos = pos2
		print(pos)
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		(i, j, d) = (float('-inf'), 0, float('inf'))
		while j < len(nums):
			if nums[j]:
				d = min(d, j - i - 1)
				if d < k:
					return False
				i = j
			j += 1
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		counter = -1
		for i in nums:
			if counter < 0:
				if i == 1:
					counter = 0
			elif i == 0:
				counter += 1
			else:
				if counter < k:
					return False
				counter = 0
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		last1 = -1
		for num in nums:
			if num == 0 and last1 != -1:
				last1 += 1
			elif num == 1 and last1 != -1:
				if last1 < k:
					return False
				last1 = 0
			elif num == 1 and last1 == -1:
				last1 = 0
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		prev = 0
		i = 0
		for num in nums:
			if num == 1:
				if prev and k > i - prev:
					return False
				prev = i + 1
			i += 1
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		last1 = -1
		tally = len(nums)
		for (idx, val) in enumerate(nums):
			if val == 1:
				last1 = idx
				if tally < k:
					return False
				tally = 0
			else:
				tally += 1
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		c = nums.count(1) - 1
		if c < 0:
			return True
		if c == 0:
			return True
		ini = nums.index(1)
		while c:
			fin = nums.index(1, ini + 1, len(nums))
			print(fin)
			if fin - ini < k + 1:
				return False
			c -= 1
			ini = fin
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		last_one = None
		for i in range(len(nums)):
			if nums[i]:
				if last_one != None and i - last_one - 1 < k:
					return False
				last_one = i
		return True


class Solution:

	def kLengthApart1(self, nums: List[int], k: int) -> bool:
		d = [i for (i, v) in enumerate(nums) if v == 1]
		for i in range(1, len(d)):
			if d[i] - d[i - 1] <= k:
				return False
		return True

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		idx = -1
		for i in range(len(nums)):
			if nums[i] == 1:
				if idx != -1 and i - idx - 1 < k:
					return False
				idx = i
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		if len(nums) == 1:
			return True
		i = 0
		while i < len(nums):
			if nums[i] == 1:
				break
			i += 1
		counter = 0
		i += 1
		while i < len(nums):
			j = i - 1
			print(nums[j], nums[i])
			if nums[j] == 0 and nums[i] == 1:
				if counter < k:
					return False
				counter = 0
			if (nums[j] == 1 or nums[j] == 0) and nums[i] == 0:
				counter += 1
			if nums[j] == 1 and nums[i] == 1 and (k >= 1):
				return False
			i += 1
			j += 1
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		p = -1000000
		n = len(nums)
		for i in range(n):
			if nums[i] == 1:
				if i - p - 1 >= k:
					p = i
				else:
					return False
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		prev = -k - 1
		for (i, n) in enumerate(nums):
			if n == 1:
				if i - prev > k:
					prev = i
				else:
					return False
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		h = defaultdict(list)
		for i in range(len(nums)):
			h[nums[i]].append(i)
		if not h[1]:
			return True
		return all([h[1][i] - h[1][i - 1] > k for i in range(1, len(h[1]))])


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		prev_one_ind = -1
		for (i, v) in enumerate(nums):
			if v == 1:
				if prev_one_ind >= 0:
					diff = i - prev_one_ind - 1
					if diff < k:
						return False
				prev_one_ind = i
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		listx = []
		for i in range(0, len(nums)):
			if nums[i] == 1:
				if listx:
					if abs(i - listx[-1]) >= k + 1:
						listx.append(i)
					else:
						return False
				else:
					listx.append(i)
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		if k > 0:
			flag = False
			last1 = -1
			for i in range(len(nums)):
				if not flag:
					if nums[i] == 1:
						flag = True
						last1 = i
				elif nums[i] == 1:
					if i - last1 - 1 < k:
						return False
					last1 = i
			return True
		else:
			return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		res = []
		start_key = 0
		while start_key != len(nums):
			if nums[start_key] == 1:
				res.append(start_key)
			start_key += 1
		zero = 0
		while zero < len(res) - 1:
			if res[zero + 1] - (res[zero] + 1) < k:
				return False
			zero += 1
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		i = 0
		while i < len(nums):
			if nums[i]:
				break
			i += 1
		j = i
		i += 1
		while i < len(nums):
			if nums[i]:
				if i - j - 1 < k:
					return False
				j = i
			i += 1
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		result = []
		n = len(nums)
		for i in range(n):
			if nums[i] == 1:
				result.append(i + 1)
		m = len(result)
		for j in range(m - 1):
			if result[j + 1] - result[j] <= k:
				return False
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		(i, j) = (0, 0)
		flag = True
		count = 0
		while i < len(nums):
			if nums[i] == 1:
				if flag:
					count = 0
					flag = False
				else:
					if count < k:
						return False
					count = 0
			else:
				count += 1
			i += 1
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		if 1 not in nums:
			return True
		prev = nums.index(1)
		if prev == len(nums) - 1:
			return True
		for i in range(prev + 1, len(nums)):
			if nums[i] == 1:
				if i - prev <= k:
					return False
				prev = i
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		index = []
		for i in range(len(nums)):
			if nums[i] == 1:
				index.append(i)
		if not index:
			return True
		if len(index) == 1:
			return True
		print(index)
		for i in range(len(index) - 1):
			print(i)
			if index[i + 1] - index[i] >= k + 1:
				continue
			else:
				return False
		return True


class Solution:

	def kLengthApart(self, nums: List[int], k: int) -> bool:
		if k == 0:
			return True
		flag = 0
		start = 0
		for i in range(len(nums)):
			if i == 0:
				if nums[i] == 1:
					start = 1
				else:
					start = 0
				continue
			if nums[i] == 0 and start == 1:
				flag += 1
			if nums[i] == 1:
				if start == 1:
					if flag < k:
						return False
				start = 1
				flag = 0
		return True