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 innums1
min(nums2)
is the smallest element innums2
|...|
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.
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
andmin(nums2) = 3
, giving us difference3 - 1 = 2
- Set
max(nums1) = 3
andmin(nums2) = 5
, giving us difference5 - 3 = 2
- Set
max(nums1) = 5
andmin(nums2) = 9
, giving us difference9 - 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 ofnums1
b
represents the minimum element ofnums2
- The partition value for this split is
b - a
(no absolute value needed sinceb > 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]
:
- After sorting:
[1, 3, 5, 9]
- Consecutive pairs and their differences:
(1, 3)
: difference =3 - 1 = 2
(3, 5)
: difference =5 - 3 = 2
(5, 9)
: difference =9 - 5 = 4
- 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 EvaluatorExample 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)
:
-
Partition at (1, 2):
nums1 = [1]
,nums2 = [2, 4, 7, 10]
max(nums1) = 1
,min(nums2) = 2
- Partition value =
|1 - 2| = 1
-
Partition at (2, 4):
nums1 = [1, 2]
,nums2 = [4, 7, 10]
max(nums1) = 2
,min(nums2) = 4
- Partition value =
|2 - 4| = 2
-
Partition at (4, 7):
nums1 = [1, 2, 4]
,nums2 = [7, 10]
max(nums1) = 4
,min(nums2) = 7
- Partition value =
|4 - 7| = 3
-
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
Which of the tree traversal order can be used to obtain elements in a binary search tree in sorted order?
Recommended Readings
Sorting Summary Comparisons We presented quite a few sorting algorithms and it is essential to know the advantages and disadvantages of each one The basic algorithms are easy to visualize and easy to learn for beginner programmers because of their simplicity As such they will suffice if you don't know any advanced
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Donβt Miss This!