Best Rust Coding Interview Questions for Beginners
2025-08-19
Rust is gaining popularity in systems programming, backend engineering, and even interviews. While most companies still test you with language-agnostic problems, being comfortable solving them in Rust can help you stand out. Below are beginner-friendly Rust coding interview questions, with real solutions and explanations.
1) Two Sum
Concepts: Hash maps, ownership, borrowing.
use std::collections::HashMap;
fn two_sum(nums: Vec<i32>, target: i32) -> Vec<i32> {
let mut map = HashMap::new();
for (i, &n) in nums.iter().enumerate() {
let need = target - n;
if let Some(&j) = map.get(&need) {
return vec![j as i32, i as i32];
}
map.insert(n, i);
}
vec![]
}
fn main() {
println!("{:?}", two_sum(vec![2,7,11,15], 9)); // [0,1]
}
2) Reverse a String
Concepts: Iterators, string handling.
fn reverse_string(s: &str) -> String {
s.chars().rev().collect()
}
fn main() {
println!("{}", reverse_string("rustacean")); // "naecatsur"
}
3) Palindrome Number
Concepts: Converting to string, iterator tricks.
fn is_palindrome(x: i32) -> bool {
let s = x.to_string();
s.chars().eq(s.chars().rev())
}
fn main() {
println!("{}", is_palindrome(121)); // true
println!("{}", is_palindrome(-121)); // false
}
4) FizzBuzz
Concepts: Pattern matching, loops.
fn fizz_buzz(n: i32) -> Vec<String> {
(1..=n)
.map(|i| match (i % 3, i % 5) {
(0, 0) => "FizzBuzz".to_string(),
(0, _) => "Fizz".to_string(),
(_, 0) => "Buzz".to_string(),
_ => i.to_string(),
})
.collect()
}
fn main() {
println!("{:?}", fizz_buzz(15));
}
5) Maximum Subarray (Kadane’s Algorithm)
Concepts: Iteration with state, std::cmp::max
.
fn max_sub_array(nums: Vec<i32>) -> i32 {
let mut cur = nums[0];
let mut best = nums[0];
for &n in &nums[1..] {
cur = std::cmp::max(n, cur + n);
best = std::cmp::max(best, cur);
}
best
}
fn main() {
println!("{}", max_sub_array(vec![-2,1,-3,4,-1,2,1,-5,4])); // 6
}
6) Merge Two Sorted Lists
Concepts: Linked lists, Option<Box<T>>
.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct ListNode {
pub val: i32,
pub next: Option<Box<ListNode>>,
}
impl ListNode {
fn new(val: i32) -> Self {
ListNode { val, next: None }
}
}
fn merge_two_lists(
l1: Option<Box<ListNode>>,
l2: Option<Box<ListNode>>,
) -> Option<Box<ListNode>> {
match (l1, l2) {
(Some(mut n1), Some(mut n2)) => {
if n1.val < n2.val {
n1.next = merge_two_lists(n1.next.take(), Some(n2));
Some(n1)
} else {
n2.next = merge_two_lists(Some(n1), n2.next.take());
Some(n2)
}
}
(None, l) => l,
(l, None) => l,
}
}
7) Valid Parentheses
Concepts: Stack, vectors.
fn is_valid(s: String) -> bool {
let mut stack = Vec::new();
for c in s.chars() {
match c {
'(' | '{' | '[' => stack.push(c),
')' => if stack.pop() != Some('(') { return false; },
'}' => if stack.pop() != Some('{') { return false; },
']' => if stack.pop() != Some('[') { return false; },
_ => {}
}
}
stack.is_empty()
}
fn main() {
println!("{}", is_valid("()[]{}".to_string())); // true
println!("{}", is_valid("(]".to_string())); // false
}
8) Climbing Stairs
Concepts: DP, iterative state.
fn climb_stairs(n: i32) -> i32 {
if n <= 2 { return n; }
let mut a = 1;
let mut b = 2;
for _ in 3..=n {
let c = a + b;
a = b;
b = c;
}
b
}
fn main() {
println!("{}", climb_stairs(5)); // 8
}
9) Binary Search
Concepts: Loops, bounds handling.
fn binary_search(nums: &[i32], target: i32) -> i32 {
let mut lo = 0;
let mut hi = nums.len() as i32 - 1;
while lo <= hi {
let mid = lo + (hi - lo) / 2;
if nums[mid as usize] == target { return mid; }
if nums[mid as usize] < target { lo = mid + 1; }
else { hi = mid - 1; }
}
-1
}
fn main() {
println!("{}", binary_search(&[1,3,5,7,9], 7)); // 3
}
10) Breadth-First Search (BFS) on a Graph
Concepts: Queue with VecDeque
.
use std::collections::VecDeque;
fn bfs(n: usize, edges: &[(usize, usize)], start: usize) -> Vec<usize> {
let mut graph = vec![vec![]; n];
for &(u, v) in edges {
graph[u].push(v);
graph[v].push(u);
}
let mut visited = vec![false; n];
let mut order = Vec::new();
let mut q = VecDeque::new();
q.push_back(start);
visited[start] = true;
while let Some(u) = q.pop_front() {
order.push(u);
for &v in &graph[u] {
if !visited[v] {
visited[v] = true;
q.push_back(v);
}
}
}
order
}
fn main() {
let edges = [(0,1),(0,2),(1,3),(1,4)];
println!("{:?}", bfs(5, &edges, 0)); // [0,1,2,3,4]
}
Interview Checklist for Rust Beginners
- Be ready to explain ownership and borrowing when passing data structures.
- Prefer iterators and pattern matching over verbose loops.
- Use Option/Result idiomatically for null/error handling.
- Keep solutions clean with
collect()
,enumerate()
,map()
, andzip()
. - For data structures, know how to use
Vec
,HashMap
,HashSet
,VecDeque
.
Final Note
Learning LeetCode in Rust trains both your algorithmic thinking and your ability to use Rust’s unique features. Mastering these beginner problems will prepare you for tougher DP, graph, and system design challenges.
If you want to see clean Rust solutions live while you practice, check out StealthCoder — it can overlay working code and explanations so you can stay focused and build confidence.