Problem overview
The function move_to_front receives a to-do list items, a vector of strings, and an index. It returns the list with the item at index taken out of its place and put at index 0. All the other items keep their relative order.
For ["wash", "shop", "cook", "read"] and index = 2, the item is "cook". It moves to the front, and "wash" and "shop" shift one place to the right: ["cook", "wash", "shop", "read"]. With index = 0 the item is already first and nothing changes.
Approach
A Vec has two methods that do exactly the two halves of the job. remove(i) takes the item out of position i, closes the gap, and hands the item back. insert(0, x) puts x at the front and shifts everything else one place right. Doing them in that order moves the item without disturbing anyone else.
Step by step
- The signature says
mut items, which lets the function change the vector it received. Callitems.remove(index)and store what it returns initem. Now the vector is one shorter, anditemholds the removed string by itself. - Call
items.insert(0, item). The string moves into the vector, and every other item shifts one place right. - End the function with
items, without a semicolon.
The solution in Rust
impl Solution {
fn move_to_front(mut items: Vec<String>, index: usize) -> Vec<String> {
let item = items.remove(index);
items.insert(0, item);
items
}
}
Two Rust details matter. The mut in the parameter list is what allows remove and insert to run; it doesn't change what callers pass. And item is a String, so insert takes ownership of it: after that line you can't use item again. That is why the code never needs a copy of the string.
Following one call
Take ["wash", "shop", "cook", "read"] and index = 2. After remove(2), item is "cook" and the list is ["wash", "shop", "read"]. After insert(0, item), the list is ["cook", "wash", "shop", "read"]. Each method shifts the items behind its position by one place, and the two shifts happen on different parts of the list, so the other items end up in their original relative order.
Why not swap
Swapping the item with the one at index 0 would put it in front, but it would also send the old first item to the item's old place, so the others would not keep their order. For ["wash", "shop", "cook", "read"], a swap would give ["cook", "shop", "wash", "read"]. The task wants the others to stay in order, and only remove followed by insert guarantees that.
Edge cases and common mistakes
- Index 0. The item is removed from the front and inserted at the front again, so the list comes back as it was.
- Duplicate words. The function moves the item at the given position, not the first matching word. With
["call", "pay", "call", "walk"]and index 2, the second"call"moves, giving["call", "call", "pay", "walk"]. - Inserting before removing. Doing
insert(0, ...)first shifts everything right, so the original index no longer points at the item. - A bad index. An index at or past the length would panic in
remove. The constraints keep it inside the list.
Testing
Results from running the function:
["wash", "shop", "cook", "read"],index = 2gives["cook", "wash", "shop", "read"].["tea", "coffee"],index = 0gives["tea", "coffee"].["call", "pay", "call", "walk"],index = 2gives["call", "call", "pay", "walk"].
