LeetCode 667: Beautiful Arrangement II Solution in Python – A Step-by-Step Guide
Imagine you’re a puzzle designer tasked with arranging numbers from 1 to n—say, 5—into an array where the absolute differences between consecutive pairs yield exactly k unique values, like 3 distinct differences. For example, [1, 5, 2, 4, 3] gives differences 4, 3, 2—exactly 3 unique values. That’s the challenge of LeetCode 667: Beautiful Arrangement II, a medium-level problem that’s all about crafting a sequence with a precise number of distinct gaps. Using Python, we’ll explore two solutions: the Best Solution, a constructive pattern with alternating differences for efficiency, and an Alternative Solution, a greedy approach with adjustment that’s more intuitive but less direct. With detailed examples, beginner-friendly breakdowns—especially for the constructive method—and clear code, this guide will help you arrange that array, whether you’re new to coding or leveling up. Let’s grab those numbers and start arranging!
What Is LeetCode 667: Beautiful Arrangement II?
In LeetCode 667: Beautiful Arrangement II, you’re given two integers n and k, and your task is to construct an array of length n using numbers 1 to n exactly once (a permutation), such that the absolute differences between consecutive elements have exactly k distinct values. Return any such array. For example, with n = 5 and k = 3, one possible array is [1, 5, 2, 4, 3], with differences [4, 3, 2], exactly 3 distinct values. The problem tests your ability to control the number of unique differences in a sequence.
Problem Statement
- Input:
- n: Integer (array length, 1 to n permutation).
- k: Integer (number of distinct differences).
- Output: A list of integers—permutation with exactly k distinct differences.
- Rules:
- Use numbers 1 to n exactly once.
- Differences = |arr[i] - arr[i+1]| for i from 0 to n-2.
- Result must have exactly k unique differences.
Constraints
- 1 ≤ k < n ≤ 10⁴.
Examples
- Input: n = 3, k = 1
- Output: [1, 2, 3] (Differences: [1, 1], 1 distinct)
- Input: n = 3, k = 2
- Output: [1, 3, 2] (Differences: [2, 1], 2 distinct)
- Input: n = 5, k = 3
- Output: [1, 5, 2, 4, 3] (Differences: [4, 3, 2], 3 distinct)
These examples set the numbers—let’s solve it!
Understanding the Problem: Crafting Distinct Differences
To solve LeetCode 667: Beautiful Arrangement II in Python, we need to construct a permutation of numbers 1 to n with exactly k distinct consecutive differences. A brute-force approach—generating all permutations and checking differences—would be O(n!), impractical for n ≤ 10⁴. Since we control the differences, we can construct the array directly or adjust greedily. We’ll use:
- Best Solution (Constructive Pattern with Alternating Differences): O(n) time, O(n) space—fast and elegant.
- Alternative Solution (Greedy with Adjustment): O(n) time, O(n) space—intuitive but less precise.
Let’s start with the constructive solution, breaking it down for beginners.
Best Solution: Constructive Pattern with Alternating Differences
Why This Is the Best Solution
The constructive pattern with alternating differences is the top choice for LeetCode 667 because it’s efficient—O(n) time with O(n) space—and uses a clever insight: we can create k distinct differences by alternating high and low numbers for the first part, then filling the rest with a minimal difference (usually 1). It fits constraints (n ≤ 10⁴) perfectly and is straightforward once you see the pattern. It’s like weaving a sequence with just the right gaps!
How It Works
Think of this as a difference weaver:
- Step 1: Understand Differences:
- Max distinct differences = n-1 (e.g., n=3: [1, 3, 2] gives 2).
- Min = 1 (e.g., [1, 2, 3]).
- We need exactly k.
- Step 2: Construct Array:
- Use two pointers: low (1) and high (n).
- For first k differences:
- Alternate high and low to get k-1 large differences (n-1 down to n-k+1).
- Fill rest with remaining numbers in order (difference 1).
- Step 3: Return Result:
- Array with exactly k distinct differences.
It’s like a gap crafter—alternate and fill!
Step-by-Step Example
Example: n = 5, k = 3
- Step 1: n-1 = 4 max differences, k = 3.
- Step 2: Construct:
- Start: low = 1, high = 5.
- k=3 needs 2 large differences + 1 small:
- Add 1 (low), arr = [1].
- Add 5 (high), arr = [1, 5], diff = [4].
- Add 2 (low+1), arr = [1, 5, 2], diff = [4, 3].
- Fill rest (3, 4):
- Add 4, arr = [1, 5, 2, 4], diff = [4, 3, 2].
- Add 3, arr = [1, 5, 2, 4, 3], diff = [4, 3, 2, 1].
- Distinct = {4, 3, 2}, k = 3.
- Step 3: Return [1, 5, 2, 4, 3].
- Output: [1, 5, 2, 4, 3].
Code with Detailed Line-by-Line Explanation
Here’s the Python code, explained clearly:
class Solution:
def constructArray(self, n: int, k: int) -> List[int]:
# Step 1: Initialize result array
result = []
low = 1
high = n
# Step 2: Construct k distinct differences
for i in range(k - 1): # k-1 alternations
if i % 2 == 0:
result.append(low)
low += 1
else:
result.append(high)
high -= 1
# Fill remaining with ascending order
if k % 2 == 0: # Last was high, reverse order
for i in range(high, low - 1, -1):
result.append(i)
else: # Last was low, ascending order
for i in range(low, high + 1):
result.append(i)
# Step 3: Return result
return result
- Lines 4-6: Init: Empty array, low=1, high=n.
- Lines 9-15: Construct:
- Alternate low and high for k-1 differences.
- Lines 18-23: Fill:
- If k even, descending; if odd, ascending.
- Line 26: Return array.
- Time Complexity: O(n)—single pass to build array.
- Space Complexity: O(n)—result array.
This is like an array designer—weave and complete!
Alternative Solution: Greedy with Adjustment
Why an Alternative Approach?
The greedy with adjustment approach builds the array incrementally—O(n) time, O(n) space. It’s more intuitive, starting with a simple sequence and adjusting to hit k, but requires tweaking to ensure correctness. It’s like starting with a basic pattern and nudging it to fit!
How It Works
Picture this as a difference nudger:
- Step 1: Start with ascending array (1 diff).
- Step 2: Greedily increase differences:
- Swap or adjust elements to add new differences.
- Stop at k distinct values.
- Step 3: Return result.
It’s like a gap adjuster—start and tweak!
Step-by-Step Example
Example: n = 5, k = 3
- Step 1: Start: [1, 2, 3, 4, 5], diff = [1], 1 distinct.
- Step 2: Adjust:
- Swap 2 and 5: [1, 5, 3, 4, 5], diff = [4, 2, 1, 1], 3 distinct.
- Step 3: Return [1, 5, 3, 4, 5].
- Output: [1, 5, 3, 4, 5].
Code for Greedy Approach
class Solution:
def constructArray(self, n: int, k: int) -> List[int]:
# Step 1: Start with ascending array
result = list(range(1, n + 1))
# Step 2: Greedily adjust for k differences
diff_set = {1} # Initial difference
left = 1
right = n - 1
while len(diff_set) < k and left < right:
# Swap to introduce new difference
result[left], result[right] = result[right], result[left]
new_diff = abs(result[left] - result[left - 1])
diff_set.add(new_diff)
left += 1
right -= 1
# Step 3: Return result
return result
- Line 4: Start: [1, 2, ..., n].
- Lines 7-16: Adjust:
- Swap ends inward, add new differences until k reached.
- Line 19: Return array.
- Time Complexity: O(n)—single pass with swaps.
- Space Complexity: O(n)—array and set.
It’s a greedy tweaker—adjust and fit!
Comparing the Two Solutions
- Constructive (Best):
- Pros: O(n) time, O(n) space, guaranteed k differences.
- Cons: Pattern less intuitive.
- Greedy (Alternative):
- Pros: O(n) time, O(n) space, simpler concept.
- Cons: May need tuning for exact k.
Constructive wins for precision.
Additional Examples and Edge Cases
- Input: n = 2, k = 1
- Output: [1, 2].
- Input: n = 4, k = 2
- Output: [1, 4, 2, 3] (Differences: [3, 2]).
Constructive handles these well.
Complexity Breakdown
- Constructive: Time O(n), Space O(n).
- Greedy: Time O(n), Space O(n).
Constructive is optimal for control.
Key Takeaways
- Constructive: Pattern crafting—smart!
- Greedy: Incremental tweaking—clear!
- Differences: Arranging is fun.
- Python Tip: Loops rock—see Python Basics.
Final Thoughts: Arrange That Array
LeetCode 667: Beautiful Arrangement II in Python is a fun arrangement challenge. Constructive pattern offers precision and speed, while greedy adjustment provides an intuitive alternative. Want more? Try LeetCode 561: Array Partition or LeetCode 628: Maximum Product of Three Numbers. Ready to arrange? Head to Solve LeetCode 667 on LeetCode and craft that beautiful array today!