{x}
blog image

Minimum Number of Operations to Make Array Continuous

You are given an integer array nums. In one operation, you can replace any element in nums with any integer.

nums is considered continuous if both of the following conditions are fulfilled:

  • All elements in nums are unique.
  • The difference between the maximum element and the minimum element in nums equals nums.length - 1.

For example, nums = [4, 2, 5, 3] is continuous, but nums = [1, 2, 3, 5, 6] is not continuous.

Return the minimum number of operations to make nums continuous.

 

Example 1:

Input: nums = [4,2,5,3]
Output: 0
Explanation: nums is already continuous.

Example 2:

Input: nums = [1,2,3,5,6]
Output: 1
Explanation: One possible solution is to change the last element to 4.
The resulting array is [1,2,3,5,4], which is continuous.

Example 3:

Input: nums = [1,10,100,1000]
Output: 3
Explanation: One possible solution is to:
- Change the second element to 2.
- Change the third element to 3.
- Change the fourth element to 4.
The resulting array is [1,2,3,4], which is continuous.

 

Constraints:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 109

Solution Explanation for Minimum Number of Operations to Make Array Continuous

This problem asks for the minimum number of operations to make an integer array continuous. An array is considered continuous if all elements are unique and the difference between the maximum and minimum elements is equal to the array's length minus one. The core idea is to identify the longest continuous sub-sequence within the array and calculate the minimum operations needed based on that.

Approach:

The most efficient approach involves these steps:

  1. Sort and Deduplicate: Sort the input array nums and remove duplicate elements. This simplifies the process of finding continuous subsequences because we only need to consider unique values.

  2. Sliding Window or Two Pointers: Iterate through the sorted and deduplicated array. For each element, consider it as the potential minimum element of a continuous subsequence. Use a sliding window (or two pointers) to find the longest continuous subsequence starting from that minimum element. The window's right boundary expands until the difference between the maximum (rightmost) and minimum (leftmost) elements exceeds nums.length - 1.

  3. Calculate Operations: For each potential continuous subsequence, the number of operations needed is simply the difference between the array's length (nums.length) and the length of the found continuous subsequence. The minimum of these operation counts is the final answer.

Time and Space Complexity Analysis

  • Time Complexity: The sorting step dominates the time complexity, resulting in O(N log N), where N is the length of the input array. The sliding window/two pointers approach has a linear time complexity of O(N) within the sorted array.

  • Space Complexity: The space complexity is primarily determined by the sorting algorithm used and any temporary storage for the deduplicated array. In most cases, this is O(N) in the worst-case scenario (e.g., all unique elements). However, in-place sorting algorithms can reduce space complexity to O(log N) or even O(1) depending on the implementation.

Code Implementation (Python)

The following Python code implements the described approach using a two-pointer technique:

from bisect import bisect_right
 
class Solution:
    def minOperations(self, nums: List[int]) -> int:
        n = len(nums)
        nums = sorted(list(set(nums)))  # Sort and remove duplicates
        min_ops = n
        left = 0
        for right, num in enumerate(nums):
            while nums[right] - nums[left] > n - 1:
                left += 1
            min_ops = min(min_ops, n - (right - left + 1))
        return min_ops

This code first sorts the unique elements and then uses a while loop to maintain the window's boundaries to find the longest sub-sequence that satisfies the condition. The bisect_right function is a more efficient alternative to using a while loop, especially for large datasets.

Code Implementation (Other Languages)

The core logic remains consistent across different languages. The primary differences lie in the syntax and library functions used for sorting and finding the maximum/minimum values. The examples below show the adaptations in Java and C++. Other languages like Go or Rust would use their respective equivalents for sorting and set operations.

Java:

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
 
class Solution {
    public int minOperations(int[] nums) {
        Set<Integer> uniqueNums = new HashSet<>();
        for (int num : nums) {
            uniqueNums.add(num);
        }
        int[] sortedNums = uniqueNums.stream().mapToInt(Integer::intValue).toArray();
        Arrays.sort(sortedNums);
 
        int n = nums.length;
        int minOps = n;
        int left = 0;
        for (int right = 0; right < sortedNums.length; right++) {
            while (sortedNums[right] - sortedNums[left] > n - 1) {
                left++;
            }
            minOps = Math.min(minOps, n - (right - left + 1));
        }
        return minOps;
    }
}

C++:

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
 
using namespace std;
 
class Solution {
public:
    int minOperations(vector<int>& nums) {
        set<int> uniqueNums(nums.begin(), nums.end());
        vector<int> sortedNums(uniqueNums.begin(), uniqueNums.end());
        sort(sortedNums.begin(), sortedNums.end());
 
        int n = nums.size();
        int minOps = n;
        int left = 0;
        for (int right = 0; right < sortedNums.size(); right++) {
            while (sortedNums[right] - sortedNums[left] > n - 1) {
                left++;
            }
            minOps = min(minOps, n - (right - left + 1));
        }
        return minOps;
    }
};

These examples show that while the language syntax varies, the underlying algorithmic approach remains the same for achieving optimal time and space complexity. Remember to adapt the code to your chosen language using equivalent data structures and functions.