Leetcode 1144. Decrease Elements To Make Array Zigzag

Problem Explanation

This problem requires us to find the number of 'moves' required to make an array a zigzag array. A zigzag array is defined as an array where every even-indexed element is greater than its adjacent elements or every odd indexed element is greater than its adjacent elements.

The challenge states that we can make a 'move' by decreasing an element in the array by 1. So we need to calculate the minimum number of times we would need to do that to achieve a zigzag array.

Example

Let's take the array nums[1,2,3]. In this array, we would need to make two moves; either decrease 2 to 0, or 3 to 1, to achieve a zigzag array.

Approach

The approach to solve this problem is to iterate over the given list and calculate how many moves are needed to make both even indexed elements or odd indexed elements smaller than their neighbors. We will maintain two counters to track the number of moves required for achieving both cases separately. After calculating, we return the smaller of the two counts as it would represent the minimum number of operations needed.

We start by initializing two counters (lets say decreasing) with zeroes.

While iterating over the list, for each element, we store the value of its left neighbor l and right neighbor r. If the index is at the boundary of the list, we assume the value of the neighbor is 1001 (since the list can contain maximum 1000 as elements as per problem constraints)

We then increment the counter at position i mod 2 (i % 2) in the decreasing list by the maximum of zero and (current value - minimum of l and r + 1).

Finally, after the loop ends, we return the minimum of the values at both indices in decreasing.

Python Solution

1
2python
3class Solution:
4    def movesToMakeZigzag(self, nums):
5        decreasing = [0] * 2
6
7        for i in range(len(nums)):
8            l = nums[i - 1] if i > 0 else 1001
9            r = nums[i + 1] if i + 1 < len(nums) else 1001
10            decreasing[i % 2] += max(0, nums[i] - min(l, r) + 1)
11
12        return min(decreasing)

Java Solution

1
2java
3class Solution {
4    public int movesToMakeZigzag(int[] nums) {
5        int[] decreasing = new int[2];
6        
7        for (int i = 0; i < nums.length; ++i) {
8            int l = i > 0 ? nums[i-1] : 1001;
9            int r = i+1 < nums.length ? nums[i+1] : 1001;
10            decreasing[i % 2] += Math.max(0, nums[i] - Math.min(l, r) + 1);
11        }
12        
13        return Math.min(decreasing[0], decreasing[1]);
14    }
15}

JavaScript Solution

1
2javascript
3var movesToMakeZigzag = function(nums) {
4    let decreasing = [0, 0];
5    
6    for (let i = 0; i < nums.length; ++i) {
7        let l = i > 0 ? nums[i-1] : 1001;
8        let r = i+1 < nums.length ? nums[i+1] : 1001;
9        decreasing[i % 2] += Math.max(0, nums[i] - Math.min(l, r) + 1);
10    }
11    
12    return Math.min(decreasing[0], decreasing[1]);    
13};

C++ Solution

1
2cpp
3class Solution {
4public:
5    int movesToMakeZigzag(vector<int>& nums) {
6        vector<int> decreasing(2);
7
8        for (int i = 0; i < nums.size(); ++i) {
9            int l = i > 0 ? nums[i - 1] : 1001;
10            int r = i + 1 < nums.size() ? nums[i + 1] : 1001;
11            decreasing[i % 2] += max(0, nums[i] - min(l, r) + 1);
12        }
13
14        return min(decreasing[0], decreasing[1]);
15    }
16};

C# Solution

1
2csharp
3public class Solution {
4    public int MovesToMakeZigzag(int[] nums) {
5        int[] decreasing = new int[2];
6        
7        for(int i=0; i< nums.Length; ++i) {
8            int l = i > 0 ? nums[i-1] : 1001;
9            int r = i+1 < nums.Length ? nums[i+1] : 1001;
10            decreasing[i%2] += Math.Max(0, nums[i] - Math.Min(l, r) + 1);
11        }
12        
13        return Math.Min(decreasing[0], decreasing[1]);
14    }
15}

Conclusion

In conclusion, we designed a solution that calculates the minimum number of moves needed to turn a given array into a zigzag array. The logic behind the solution is relatively straightforward once understood, and we used a simple array to track the number of operations required for two different possibilities and then return the minimum of the two.This solution exercises an excellent understanding of array manipulation and subtle conditional logic. The problem was approached using a simple but effective technique of iterating over the array and calculating the number of operations needed to turn the array into a zigzag pattern.

The provided solutions are optimal, as they require only a single iteration over the input list/ array. The space complexity of the solution is constant, which makes it highly efficient even for large input arrays. So, irrespective of the programming language used, Python, Java, Javascript, or C++, the time and space efficiency remains the same.

Moreover, since we used elementary operations and built-in array or list operations, the solution is easy to understand and should be straightforward to implement in different programming languages. Hence, this problem and its solution serve as a good exercise for understanding array manipulation, conditions, and iteration in any of these programming languages.

Additional steps you can take to understand and validate the solution better would be by using more test cases. Testing edge cases such as the smallest possible array, largest possible array, and arrays with elements at the limit of the allowed value is an excellent way to confirm your solution's robustness and efficiency.


Got a question? Ask the Teaching Assistant anything you don't understand.

Still not clear? Ask in the Forum,  Discord or Submit the part you don't understand to our editors.


TA 👨‍🏫