Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Move from brute-force thinking to an efficient approach using array strategy.
Given an integer array nums, partition it into two (contiguous) subarrays left and right so that:
left is less than or equal to every element in right.left and right are non-empty.left has the smallest possible size.Return the length of left after such a partitioning.
Test cases are generated such that partitioning exists.
Example 1:
Input: nums = [5,0,3,8,6] Output: 3 Explanation: left = [5,0,3], right = [8,6]
Example 2:
Input: nums = [1,1,1,0,6,12] Output: 4 Explanation: left = [1,1,1,0], right = [6,12]
Constraints:
2 <= nums.length <= 1050 <= nums[i] <= 106Problem summary: Given an integer array nums, partition it into two (contiguous) subarrays left and right so that: Every element in left is less than or equal to every element in right. left and right are non-empty. left has the smallest possible size. Return the length of left after such a partitioning. Test cases are generated such that partitioning exists.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array
[5,0,3,8,6]
[1,1,1,0,6,12]
sum-of-beauty-in-the-array)optimal-partition-of-string)minimum-index-of-a-valid-split)maximum-strength-of-k-disjoint-subarrays)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #915: Partition Array into Disjoint Intervals
class Solution {
public int partitionDisjoint(int[] nums) {
int n = nums.length;
int[] mi = new int[n + 1];
mi[n] = nums[n - 1];
for (int i = n - 1; i >= 0; --i) {
mi[i] = Math.min(nums[i], mi[i + 1]);
}
int mx = 0;
for (int i = 1;; ++i) {
int v = nums[i - 1];
mx = Math.max(mx, v);
if (mx <= mi[i]) {
return i;
}
}
}
}
// Accepted solution for LeetCode #915: Partition Array into Disjoint Intervals
func partitionDisjoint(nums []int) int {
n := len(nums)
mi := make([]int, n+1)
mi[n] = nums[n-1]
for i := n - 1; i >= 0; i-- {
mi[i] = min(nums[i], mi[i+1])
}
mx := 0
for i := 1; ; i++ {
v := nums[i-1]
mx = max(mx, v)
if mx <= mi[i] {
return i
}
}
}
# Accepted solution for LeetCode #915: Partition Array into Disjoint Intervals
class Solution:
def partitionDisjoint(self, nums: List[int]) -> int:
n = len(nums)
mi = [inf] * (n + 1)
for i in range(n - 1, -1, -1):
mi[i] = min(nums[i], mi[i + 1])
mx = 0
for i, v in enumerate(nums, 1):
mx = max(mx, v)
if mx <= mi[i]:
return i
// Accepted solution for LeetCode #915: Partition Array into Disjoint Intervals
struct Solution;
impl Solution {
fn partition_disjoint(a: Vec<i32>) -> i32 {
let n = a.len();
let mut left = vec![0; n];
let mut right = vec![0; n];
let mut min = std::i32::MAX;
let mut max = std::i32::MIN;
for i in (0..n).rev() {
min = min.min(a[i]);
right[i] = min;
}
for i in 0..n {
max = max.max(a[i]);
left[i] = max;
}
for i in 1..n {
if right[i] >= left[i - 1] {
return i as i32;
}
}
0
}
}
#[test]
fn test() {
let a = vec![5, 0, 3, 8, 6];
let res = 3;
assert_eq!(Solution::partition_disjoint(a), res);
let a = vec![1, 1, 1, 0, 6, 12];
let res = 4;
assert_eq!(Solution::partition_disjoint(a), res);
}
// Accepted solution for LeetCode #915: Partition Array into Disjoint Intervals
// Auto-generated TypeScript example from java.
function exampleSolution(): void {
}
// Reference (java):
// // Accepted solution for LeetCode #915: Partition Array into Disjoint Intervals
// class Solution {
// public int partitionDisjoint(int[] nums) {
// int n = nums.length;
// int[] mi = new int[n + 1];
// mi[n] = nums[n - 1];
// for (int i = n - 1; i >= 0; --i) {
// mi[i] = Math.min(nums[i], mi[i + 1]);
// }
// int mx = 0;
// for (int i = 1;; ++i) {
// int v = nums[i - 1];
// mx = Math.max(mx, v);
// if (mx <= mi[i]) {
// return i;
// }
// }
// }
// }
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.