📖 Scenario: You are working on a feature for a puzzle game where players can rearrange numbers to find the next higher combination. You need to write a program that finds the next permutation of a list of numbers.
🎯 Goal: Build a Rust program that takes an array of numbers and rearranges it to the next lexicographically greater permutation. If such a permutation is not possible, rearrange it to the lowest possible order (sorted ascending).
📋 What You'll Learn
Create a vector called nums with the exact values [1, 2, 3]
Create a variable called i and initialize it to the last index minus one of nums
Implement the next permutation logic using a loop to find the first decreasing element from the right
Print the final state of nums after rearranging
💡 Why This Matters
🌍 Real World
Finding the next permutation is useful in puzzles, games, and generating combinations in order.
💼 Career
Understanding permutations and array manipulation is important for coding interviews and algorithm design.
Progress0 / 4 steps
1
Create the initial array
Create a vector called nums with the exact values [1, 2, 3].
DSA Rust
Hint
Use let mut nums = vec![1, 2, 3]; to create a mutable vector.
2
Set the starting index for scanning
Create a mutable variable called i and set it to nums.len() - 2.
DSA Rust
Hint
Use let mut i = nums.len() as i32 - 2; to start from the second last index.
3
Find the first decreasing element from the right
Use a while loop with the condition i >= 0 && nums[i as usize] >= nums[(i + 1) as usize] to find the first index i where nums[i] is less than nums[i + 1]. Inside the loop, decrease i by 1.
DSA Rust
Hint
Use a while loop to move i left until you find a smaller number than its next.
4
Print the final array after next permutation
Print the vector nums using println!("{:?}", nums); after the logic.
DSA Rust
Hint
Use println!("{:?}", nums); to print the vector.
Practice
(1/5)
1. What does the next_permutation algorithm do to an array of numbers?
easy
A. It rearranges the array to the next lexicographically greater permutation.
B. It sorts the array in ascending order.
C. It reverses the array.
D. It finds the maximum element in the array.
Solution
Step 1: Understand the purpose of next_permutation
The algorithm finds the next arrangement of elements that is just larger than the current one in dictionary order.
Step 2: Compare with other options
Sorting or reversing changes order but does not guarantee the next lexicographical permutation. Finding max element is unrelated.
Final Answer:
It rearranges the array to the next lexicographically greater permutation. -> Option A
Quick Check:
Next permutation = next lexicographically greater order [OK]
Hint: Next permutation means next bigger order arrangement [OK]
Common Mistakes:
Confusing next permutation with sorting
Thinking it reverses the array always
Assuming it finds max element
2. Which of the following Rust code snippets correctly swaps two elements in a vector nums at indices i and j?
easy
A. nums.swap(i, j) -> ();
B. nums[i] = nums[j]; nums[j] = nums[i];
C. nums.swap(i, j);
D. nums.swap_elements(i, j);
Solution
Step 1: Recall Rust vector swap method
Rust's standard Vec<T> has a method swap(i, j) to exchange elements at indices i and j.
Step 2: Check other options for correctness
nums[i] = nums[j]; nums[j] = nums[i]; incorrectly assigns values without temporary storage, causing wrong swap. nums.swap_elements(i, j); uses a non-existent method. nums.swap(i, j) -> (); has invalid syntax.
Final Answer:
nums.swap(i, j); -> Option C
Quick Check:
Correct swap method = nums.swap(i, j) [OK]
Hint: Use nums.swap(i, j) to swap elements in Rust vector [OK]
Common Mistakes:
Assigning without temp variable causing overwrite
Using non-existent methods
Incorrect syntax with arrows or extra symbols
3. What is the output of the following Rust code that finds the next permutation of nums = vec![1, 3, 2]?
let mut nums = vec![1, 3, 2];
if next_permutation(&mut nums) {
println!("{:?}", nums);
} else {
println!("No next permutation");
}
fn next_permutation(nums: &mut Vec<i32>) -> bool {
let n = nums.len();
if n < 2 { return false; }
let mut i = n - 2;
while i != usize::MAX && nums[i] >= nums[i + 1] {
if i == 0 { break; }
i -= 1;
}
if i == usize::MAX || nums[i] >= nums[i + 1] {
nums.reverse();
return false;
}
let mut j = n - 1;
while nums[j] <= nums[i] {
j -= 1;
}
nums.swap(i, j);
nums[i + 1..].reverse();
true
}
medium
A. [2, 1, 3]
B. [1, 2, 3]
C. [1, 3, 2]
D. No next permutation
Solution
Step 1: Identify pivot index i
Starting from right, find i where nums[i] < nums[i+1]. For [1,3,2], i=0 because 1 < 3.
Step 2: Find j to swap with i
From right, find j where nums[j] > nums[i]. Here j=2 (value 2 > 1).
Step 3: Swap and reverse suffix
Swap nums[0] and nums[2]: [2,3,1]. Then reverse suffix after i: reverse [3,1] to [1,3]. Result: [2,1,3].
Step 4: Check code logic carefully
Code breaks loop early if i=0 and condition met, so i=0 is pivot. But code returns false and reverses if no pivot found. Here pivot found, so returns true and prints new nums.
Final Answer:
[2, 1, 3] -> Option A
Quick Check:
Next permutation of [1,3,2] = [2,1,3] [OK]
Hint: Find pivot i, swap with j, reverse suffix [OK]
Common Mistakes:
Not reversing suffix after swap
Wrong pivot index calculation
Confusing when to return false
4. The following Rust function attempts to implement next permutation but has a bug. What is the bug?
fn next_permutation(nums: &mut Vec<i32>) -> bool {
let n = nums.len();
if n < 2 { return false; }
let mut i = n - 2;
while nums[i] >= nums[i + 1] {
i -= 1;
}
if nums[i] >= nums[i + 1] {
nums.reverse();
return false;
}
let mut j = n - 1;
while nums[j] <= nums[i] {
j -= 1;
}
nums.swap(i, j);
nums[i + 1..].reverse();
true
}
medium
A. The suffix reversal is missing.
B. The loop misses checking when i == 0, causing panic on underflow.
C. The swap method is used incorrectly.
D. The function does not return a boolean.
Solution
Step 1: Analyze the while loop condition
The loop uses while nums[i] >= nums[i + 1] and decrements i. When i reaches 0 and condition holds, next decrement causes underflow (usize wraps to large number).
Step 2: Check consequences
This causes panic or incorrect behavior. The correct approach is to use i != usize::MAX or check before decrementing to avoid underflow.
Final Answer:
The loop misses checking when i == 0, causing panic on underflow. -> Option B
Quick Check:
Loop underflow bug = missing i == 0 check [OK]
Hint: Check loop index underflow when decrementing unsigned integers [OK]
Common Mistakes:
Ignoring unsigned integer underflow
Incorrect swap usage
Forgetting to reverse suffix
5. Given a vector nums = vec![3, 2, 1], which is the highest permutation, what will be the state of nums after applying the next permutation function that returns false when no next permutation exists?
hard
A. [3, 2, 1]
B. Original vector unchanged
C. Empty vector
D. [1, 2, 3]
Solution
Step 1: Identify if next permutation exists
For [3, 2, 1], the array is in descending order, which is the highest permutation. No next permutation exists.
Step 2: Apply algorithm behavior when no next permutation
The algorithm reverses the entire array to the lowest permutation and returns false.