Facebook Pixel

2740. Find the Value of the Partition

Problem Description

You are given a positive integer array nums. Your task is to split this array into two non-empty arrays, nums1 and nums2, such that every element from the original array belongs to exactly one of these two arrays.

The partition value is calculated as |max(nums1) - min(nums2)|, where:

  • max(nums1) is the largest element in nums1
  • min(nums2) is the smallest element in nums2
  • |...| denotes the absolute value

Your goal is to find a way to partition the array such that this partition value is minimized, and return this minimum partition value.

For example, if you have an array [1, 2, 3, 4], you could partition it as nums1 = [1, 2] and nums2 = [3, 4]. The partition value would be |max([1, 2]) - min([3, 4])| = |2 - 3| = 1.

The key insight is that to minimize |max(nums1) - min(nums2)|, we want the maximum of nums1 and the minimum of nums2 to be as close as possible. After sorting the array, the optimal partition can be found by checking adjacent elements - one serving as the maximum of nums1 and the other as the minimum of nums2. The solution iterates through all adjacent pairs in the sorted array and returns the minimum difference found.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

Let's think about what we're trying to minimize: |max(nums1) - min(nums2)|. This value represents the gap between the largest element in the first partition and the smallest element in the second partition.

To minimize this gap, we want these two values to be as close as possible. Here's the key observation: imagine we have sorted the array. If we pick any element as max(nums1), then all elements smaller than or equal to it could potentially be in nums1, while all elements larger than it must be in nums2.

Since we want to minimize the difference between max(nums1) and min(nums2), and min(nums2) must be larger than max(nums1) (otherwise that element could be in nums1 instead), the best choice for min(nums2) would be the smallest element that's larger than max(nums1).

In a sorted array, the smallest element larger than any given element is simply the next element in the sequence. This means that the optimal partition will always have max(nums1) and min(nums2) as consecutive elements in the sorted array.

For example, if we have sorted array [1, 3, 5, 9], we could:

  • Set max(nums1) = 1 and min(nums2) = 3, giving us difference 3 - 1 = 2
  • Set max(nums1) = 3 and min(nums2) = 5, giving us difference 5 - 3 = 2
  • Set max(nums1) = 5 and min(nums2) = 9, giving us difference 9 - 5 = 4

The minimum difference is 2, which occurs between consecutive elements. This is why the solution simply sorts the array and finds the minimum difference between adjacent elements - this represents the optimal way to partition the array.

Learn more about Sorting patterns.

Solution Approach

The implementation follows a straightforward approach based on our intuition that the optimal partition occurs at consecutive elements in a sorted array.

Step 1: Sort the array

nums.sort()

We first sort the array in ascending order. This allows us to easily identify which elements should be adjacent to minimize the partition value. Sorting takes O(n log n) time complexity.

Step 2: Find minimum difference between adjacent elements

return min(b - a for a, b in pairwise(nums))

After sorting, we iterate through all consecutive pairs of elements using the pairwise() function. The pairwise() function creates pairs of consecutive elements: (nums[0], nums[1]), (nums[1], nums[2]), ..., (nums[n-2], nums[n-1]).

For each pair (a, b) where a < b:

  • a represents the maximum element of nums1
  • b represents the minimum element of nums2
  • The partition value for this split is b - a (no absolute value needed since b > a in sorted array)

We calculate the difference b - a for each consecutive pair and return the minimum among all these differences.

Example walkthrough: For nums = [5, 1, 9, 3]:

  1. After sorting: [1, 3, 5, 9]
  2. Consecutive pairs and their differences:
    • (1, 3): difference = 3 - 1 = 2
    • (3, 5): difference = 5 - 3 = 2
    • (5, 9): difference = 9 - 5 = 4
  3. Return minimum difference = 2

The time complexity is O(n log n) due to sorting, and the space complexity is O(1) if we don't count the space used by sorting algorithm.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through the solution with nums = [7, 2, 10, 4, 1]:

Step 1: Sort the array

  • Original: [7, 2, 10, 4, 1]
  • Sorted: [1, 2, 4, 7, 10]

Step 2: Check all possible partitions using adjacent elements

For each adjacent pair, the left element becomes max(nums1) and the right element becomes min(nums2):

  1. Partition at (1, 2):

    • nums1 = [1], nums2 = [2, 4, 7, 10]
    • max(nums1) = 1, min(nums2) = 2
    • Partition value = |1 - 2| = 1
  2. Partition at (2, 4):

    • nums1 = [1, 2], nums2 = [4, 7, 10]
    • max(nums1) = 2, min(nums2) = 4
    • Partition value = |2 - 4| = 2
  3. Partition at (4, 7):

    • nums1 = [1, 2, 4], nums2 = [7, 10]
    • max(nums1) = 4, min(nums2) = 7
    • Partition value = |4 - 7| = 3
  4. Partition at (7, 10):

    • nums1 = [1, 2, 4, 7], nums2 = [10]
    • max(nums1) = 7, min(nums2) = 10
    • Partition value = |7 - 10| = 3

Step 3: Return the minimum partition value

  • All partition values: [1, 2, 3, 3]
  • Minimum = 1

The optimal partition is nums1 = [1] and nums2 = [2, 4, 7, 10] with a partition value of 1.

Solution Implementation

1class Solution:
2    def findValueOfPartition(self, nums: List[int]) -> int:
3        # Sort the array to ensure adjacent elements have minimum difference
4        nums.sort()
5      
6        # Find the minimum difference between consecutive elements
7        # This represents the minimum value of partition
8        min_difference = float('inf')
9        for i in range(1, len(nums)):
10            current_difference = nums[i] - nums[i - 1]
11            min_difference = min(min_difference, current_difference)
12      
13        return min_difference
14```
15
16Note: The original code uses `pairwise` which is available in Python 3.10+. The rewritten version uses a standard loop approach that works in Python 3.x versions. If you specifically need Python 3.10+ with `pairwise`:
17
18```python3
19from itertools import pairwise
20from typing import List
21
22class Solution:
23    def findValueOfPartition(self, nums: List[int]) -> int:
24        # Sort the array to ensure adjacent elements have minimum difference
25        nums.sort()
26      
27        # Find minimum difference between all consecutive pairs
28        # pairwise(nums) creates pairs: (nums[0], nums[1]), (nums[1], nums[2]), ...
29        return min(b - a for a, b in pairwise(nums))
30
1class Solution {
2    public int findValueOfPartition(int[] nums) {
3        // Sort the array in ascending order
4        Arrays.sort(nums);
5      
6        // Initialize minimum difference to a large value (2^30)
7        int minDifference = 1 << 30;
8      
9        // Iterate through adjacent elements to find minimum difference
10        for (int i = 1; i < nums.length; i++) {
11            // Calculate difference between consecutive elements
12            int currentDifference = nums[i] - nums[i - 1];
13          
14            // Update minimum difference if current is smaller
15            minDifference = Math.min(minDifference, currentDifference);
16        }
17      
18        // Return the minimum difference found
19        return minDifference;
20    }
21}
22
1class Solution {
2public:
3    int findValueOfPartition(vector<int>& nums) {
4        // Sort the array in ascending order
5        sort(nums.begin(), nums.end());
6      
7        // Initialize minimum difference with a large value (2^30)
8        int minDifference = 1 << 30;
9      
10        // Iterate through consecutive elements to find minimum difference
11        // The minimum difference between consecutive elements in sorted array
12        // represents the minimum partition value
13        for (int i = 1; i < nums.size(); ++i) {
14            // Update minimum difference if current consecutive difference is smaller
15            minDifference = min(minDifference, nums[i] - nums[i - 1]);
16        }
17      
18        // Return the minimum partition value found
19        return minDifference;
20    }
21};
22
1/**
2 * Finds the minimum absolute difference between adjacent elements after sorting
3 * This represents the value of partition where we split the array into two non-empty parts
4 * 
5 * @param nums - The input array of numbers
6 * @returns The minimum absolute difference between any two adjacent elements after sorting
7 */
8function findValueOfPartition(nums: number[]): number {
9    // Sort the array in ascending order
10    nums.sort((a: number, b: number) => a - b);
11  
12    // Initialize minimum difference to infinity
13    let minDifference: number = Infinity;
14  
15    // Iterate through adjacent pairs to find the minimum difference
16    for (let i: number = 1; i < nums.length; i++) {
17        // Calculate absolute difference between current and previous element
18        const currentDifference: number = Math.abs(nums[i] - nums[i - 1]);
19      
20        // Update minimum difference if current difference is smaller
21        minDifference = Math.min(minDifference, currentDifference);
22    }
23  
24    return minDifference;
25}
26

Time and Space Complexity

Time Complexity: O(n Γ— log n)

The time complexity is dominated by the sorting operation nums.sort(), which takes O(n Γ— log n) time where n is the length of the input array. After sorting, the code iterates through adjacent pairs using pairwise(nums) to find the minimum difference, which takes O(n) time. Since O(n Γ— log n) + O(n) = O(n Γ— log n), the overall time complexity is O(n Γ— log n).

Space Complexity: O(log n)

The space complexity comes from the sorting algorithm. Python's built-in sort() method uses Timsort, which requires O(log n) space for the recursive call stack in the worst case. The pairwise iterator and the variable storing the minimum value use only O(1) additional space. Therefore, the total space complexity is O(log n).

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Forgetting to sort the array

One of the most common mistakes is attempting to find the minimum partition value without first sorting the array. Without sorting, checking adjacent elements in the original array won't guarantee the optimal partition.

Incorrect approach:

def findValueOfPartition(self, nums: List[int]) -> int:
    min_difference = float('inf')
    for i in range(1, len(nums)):
        # This won't work with unsorted array!
        current_difference = abs(nums[i] - nums[i - 1])
        min_difference = min(min_difference, current_difference)
    return min_difference

Why it fails: For nums = [5, 1, 9, 3], this would check pairs (5,1), (1,9), (9,3) instead of the sorted pairs (1,3), (3,5), (5,9), potentially missing the optimal partition.

2. Misunderstanding the partition requirement

Some might think we need to maintain the original order or create contiguous subarrays, leading to overly complex solutions.

Incorrect interpretation:

def findValueOfPartition(self, nums: List[int]) -> int:
    min_val = float('inf')
    # Trying to split at each position maintaining order
    for i in range(1, len(nums)):
        left = nums[:i]
        right = nums[i:]
        min_val = min(min_val, abs(max(left) - min(right)))
    return min_val

Solution: Remember that elements can be placed in any order within nums1 and nums2. The only requirement is that every element belongs to exactly one partition.

3. Using absolute value unnecessarily after sorting

After sorting, we know that nums[i] < nums[i+1], so nums[i+1] - nums[i] is always positive. Using abs() adds unnecessary computation.

Redundant code:

min_difference = min(min_difference, abs(nums[i] - nums[i - 1]))  # abs() not needed

Better approach:

min_difference = min(min_difference, nums[i] - nums[i - 1])

4. Incorrect boundary handling

Starting the loop from index 0 instead of 1, or going up to len(nums) instead of len(nums)-1 when using nums[i+1].

Off-by-one error:

# Wrong: starts from 0
for i in range(len(nums) - 1):
    current_difference = nums[i] - nums[i - 1]  # nums[-1] when i=0!

Correct approach:

# Start from 1 when using nums[i-1]
for i in range(1, len(nums)):
    current_difference = nums[i] - nums[i - 1]

5. Not handling edge cases

While the problem states we need two non-empty arrays, forgetting to consider minimum array size (n β‰₯ 2) could lead to errors.

Defensive programming:

def findValueOfPartition(self, nums: List[int]) -> int:
    if len(nums) < 2:
        return 0  # or raise an exception
  
    nums.sort()
    min_difference = float('inf')
    for i in range(1, len(nums)):
        min_difference = min(min_difference, nums[i] - nums[i - 1])
    return min_difference
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Which of the tree traversal order can be used to obtain elements in a binary search tree in sorted order?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More