Problem overview
The method MoveToFront receives a to-do list items, a List<string>, and a number index. It returns the list with the item at index moved to the front: the item leaves its place and goes to index 0, and the other items keep their order.
For ["wash", "shop", "cook", "read"] and index = 2, the item at index 2 is "cook". It moves to the front, and "wash" and "shop" shift one place to the right, giving ["cook", "wash", "shop", "read"]. For ["tea", "coffee"] and index = 0, the item is already at the front, so nothing changes. In ["call", "pay", "call", "walk"] with index = 2, the word "call" appears twice, and the one at index 2 is the one that moves, giving ["call", "call", "pay", "walk"].
Approach
A list can remove an item at a position and insert an item at a position, and moving to the front is exactly those two operations in order: take the item out of its old place, then put it in at index 0.
The order matters. RemoveAt does not give the item back, so read it first and keep it in a variable. Then remove it by index. Then insert it at index 0, which pushes every other item one place to the right. The items that were behind the removed one closed the gap, and the items in front of it shift right again, so everyone ends up in the right order.
Step by step
- Save the item. Read
items[index]into astringnameditem. After the next step it would no longer be in the list. - Remove it.
items.RemoveAt(index)deletes the item at that position, and the items after it move one place left. - Insert it at the front.
items.Insert(0, item)takes the index first and the value second. Every other item moves one place right. Whenindexis 0, the item simply goes back where it was. - Return
items.
The solution in C#
class Solution {
public List<string> MoveToFront(List<string> items, int index) {
string item = items[index];
items.RemoveAt(index);
items.Insert(0, item);
return items;
}
}
Running it on the three examples gives these lists, as words separated by spaces:
cook wash shop read
tea coffee
call call pay walk
The C# details worth knowing:
- The list is changed in place. A
List<T>is a reference type, so the method edits the caller's list and returns the very same list. No copy is made. - Index versus value.
RemoveAt(index)removes by position.Remove(item)removes the first item equal to the value. - Insert takes the index first.
Insert(0, item)reads as "at position 0, put this". - Strings compare by content in C#, but this solution never compares them: it works by position only.
Edge cases and common mistakes
- Index 0. Remove and insert cancel out, and the list is as it was.
- The last index. Moving
"c"in["a", "b", "c"]gives["c", "a", "b"]. - Duplicates and
Remove. Code that callsitems.Remove(item)deletes the first matching word, not the one atindex. On["call", "pay", "call", "walk"]with index 2 it removes the first"call", inserts"call"at the front again, and returns["call", "pay", "call", "walk"], which is wrong. Removing by index avoids the problem. - Inserting before removing. If you call
Insert(0, items[index])first, every index behind it moves up by one. ThenRemoveAt(index)removes the wrong item: on the first example it produces["cook", "wash", "cook", "read"]. Remove first, or useindex + 1. - Losing the item. Calling
RemoveAtbefore saving the item leaves nothing to insert.
Testing
["wash", "shop", "cook", "read"], index 2 gives["cook", "wash", "shop", "read"].["tea", "coffee"], index 0 gives["tea", "coffee"].["call", "pay", "call", "walk"], index 2 gives["call", "call", "pay", "walk"].["a", "b", "c"], index 2 gives["c", "a", "b"].
