Solving Leetcode Interviews in Seconds with AI: Minimum Moves to Pick K Ones
Introduction
In this blog post, we will explore how to solve the LeetCode problem "3086" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.
Problem Statement
You are given a binary array nums of length n, a positive integer k and a non-negative integer maxChanges. Alice plays a game, where the goal is for Alice to pick up k ones from nums using the minimum number of moves. When the game starts, Alice picks up any index aliceIndex in the range [0, n - 1] and stands there. If nums[aliceIndex] == 1 , Alice picks up the one and nums[aliceIndex] becomes 0(this does not count as a move). After this, Alice can make any number of moves (including zero) where in each move Alice must perform exactly one of the following actions: Select any index j != aliceIndex such that nums[j] == 0 and set nums[j] = 1. This action can be performed at most maxChanges times. Select any two adjacent indices x and y (|x - y| == 1) such that nums[x] == 1, nums[y] == 0, then swap their values (set nums[y] = 1 and nums[x] = 0). If y == aliceIndex, Alice picks up the one after this move and nums[y] becomes 0. Return the minimum number of moves required by Alice to pick exactly k ones. Example 1: Input: nums = [1,1,0,0,0,1,1,0,0,1], k = 3, maxChanges = 1 Output: 3 Explanation: Alice can pick up 3 ones in 3 moves, if Alice performs the following actions in each move when standing at aliceIndex == 1: At the start of the game Alice picks up the one and nums[1] becomes 0. nums becomes [1,0,0,0,0,1,1,0,0,1]. Select j == 2 and perform an action of the first type. nums becomes [1,0,1,0,0,1,1,0,0,1] Select x == 2 and y == 1, and perform an action of the second type. nums becomes [1,1,0,0,0,1,1,0,0,1]. As y == aliceIndex, Alice picks up the one and nums becomes [1,0,0,0,0,1,1,0,0,1]. Select x == 0 and y == 1, and perform an action of the second type. nums becomes [0,1,0,0,0,1,1,0,0,1]. As y == aliceIndex, Alice picks up the one and nums becomes [0,0,0,0,0,1,1,0,0,1]. Note that it may be possible for Alice to pick up 3 ones using some other sequence of 3 moves. Example 2: Input: nums = [0,0,0,0], k = 2, maxChanges = 3 Output: 4 Explanation: Alice can pick up 2 ones in 4 moves, if Alice performs the following actions in each move when standing at aliceIndex == 0: Select j == 1 and perform an action of the first type. nums becomes [0,1,0,0]. Select x == 1 and y == 0, and perform an action of the second type. nums becomes [1,0,0,0]. As y == aliceIndex, Alice picks up the one and nums becomes [0,0,0,0]. Select j == 1 again and perform an action of the first type. nums becomes [0,1,0,0]. Select x == 1 and y == 0 again, and perform an action of the second type. nums becomes [1,0,0,0]. As y == aliceIndex, Alice picks up the one and nums becomes [0,0,0,0]. Constraints: 2 <= n <= 105 0 <= nums[i] <= 1 1 <= k <= 105 0 <= maxChanges <= 105 maxChanges + sum(nums) >= k
Explanation
Here's a breakdown of the solution:
- Core Idea: Iterate through each index as a potential starting point (
aliceIndex). For eachaliceIndex, calculate the minimum moves required to pick upkones. This involves finding thek - 1nearest ones (excluding the one ataliceIndexif it exists) and computing the cost to bring them toaliceIndex. This cost is calculated using a combination of swaps (adjacent moves) and changes (flipping a 0 to a 1). - Optimization: Prioritize bringing closer ones with swaps. If swaps aren't enough to reach
k-1ones, use changes. This is achieved using a min-heap to efficiently track distances to ones and a greedy approach to balance swaps and changes. Edge Cases: Handle the case where the initial
nums[aliceIndex]is 1 by not counting it as a move, and handle edge cases where there are fewer thankones available.Complexity: O(n (k log(n))), where n is the length of the input array and k is the number of ones to pick. The storage complexity is O(n).
Code
import heapq
def solve():
nums, k, maxChanges = input_data
n = len(nums)
ans = float('inf')
for aliceIndex in range(n):
moves = 0
changes_used = 0
ones_picked = 0
temp_nums = nums[:]
if temp_nums[aliceIndex] == 1:
temp_nums[aliceIndex] = 0
ones_picked += 1
available_ones = []
for i in range(n):
if i != aliceIndex and temp_nums[i] == 1:
heapq.heappush(available_ones, (abs(i - aliceIndex), i))
needed_ones = k - ones_picked
ones_positions = []
temp_nums_for_changes = temp_nums[:]
for i in range(n):
if i != aliceIndex and temp_nums_for_changes[i] == 0:
ones_positions.append(i)
ones_positions.sort(key=lambda x: abs(x - aliceIndex))
ones_added = 0
for i in range(min(maxChanges, needed_ones)):
if i < len(ones_positions):
available_ones.append((abs(ones_positions[i] - aliceIndex), ones_positions[i]))
ones_added += 1
available_ones.sort()
moves_required = 0
changes_required = 0
ones_taken = 0
available_ones_indexed = []
for i in range(n):
if i != aliceIndex and nums[i] == 1:
available_ones_indexed.append((abs(i-aliceIndex),i))
if i != aliceIndex and nums[i] == 0:
ones_positions.append((abs(i-aliceIndex),i))
available_ones = sorted(available_ones)
needed_ones = k - ones_picked
for dist, index in available_ones:
if ones_taken < needed_ones:
if nums[index] == 1:
moves_required += dist
ones_taken += 1
else:
if changes_used < maxChanges and ones_taken < needed_ones:
moves_required += dist
changes_used += 1
ones_taken += 1
else:
break
if ones_taken < needed_ones:
moves_required = float('inf')
ans = min(ans, moves_required)
return ans if ans != float('inf') else -1
input_data = None
if __name__ == "__main__":
nums = list(map(int, input().split()))
k, maxChanges = map(int, input().split())
input_data = nums, k, maxChanges
result = solve()
print(result)