Skip to main content

Command Palette

Search for a command to run...

Solving Leetcode Interviews in Seconds with AI: Minimum Moves to Pick K Ones

Updated
5 min read

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 each aliceIndex, calculate the minimum moves required to pick up k ones. This involves finding the k - 1 nearest ones (excluding the one at aliceIndex if it exists) and computing the cost to bring them to aliceIndex. 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-1 ones, 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 than k ones 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)

More from this blog

C

Chatmagic blog

2894 posts