Rust no LeetCode: Resolvendo problemas e aprimorando habilidades

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Rust no LeetCode: Transição do Python para o pensamento sistêmico

\n\n

Se você veio para o PythonLib, provavelmente já conhece Python. Você sabe escrever soluções concisas em uma linha e usa a tipagem dinâmica como algo natural. Mas o mundo não para. Cada vez mais, em entrevistas para empresas de ponta (e não só), pedem para escrever código em Rust. Por quê? Porque Rust é uma linguagem que combina a velocidade do C com a segurança de memória, e o LeetCode é o campo de treinamento ideal para aperfeiçoar essa habilidade.

\n\n

Neste artigo, não vamos apenas passar pela sintaxe. Vamos analisar como pensar no paradigma do Rust ao resolver problemas algorítmicos, quais estruturas de dados usar e como não se afogar no borrow checker. Vamos nessa!

\n\n

Por que LeetCode em Rust é um desafio e uma vantagem?

\n\n

A maioria das soluções no LeetCode é escrita em Python ou Java. Rust, por outro lado, faz você pensar sobre memória, propriedade e tempo de vida. Parece difícil, mas é exatamente isso que o torna um engenheiro mais forte. Ao resolver problemas em Rust, você automaticamente aprende:

\n\n
    \n
  • Sistema de Propriedade (Ownership) — a principal característica da linguagem.
  • \n
  • Empréstimo (Borrowing) e referências mutáveis/imutáveis.
  • \n
  • Iteradores eficientes sem alocações desnecessárias.
  • \n
  • Trabalho com Option e Result em vez de exceções.
  • \n
\n\n

Se você veio do Python, os primeiros 10 problemas parecerão uma tortura. Mas quando você entender como o compilador o protege de null pointer e condições de corrida, vai se apaixonar por essa linguagem.

\n\n

O que estudar antes de começar?

\n\n

Antes de se jogar nos problemas, vamos analisar o kit de ferramentas. Sem ele, você escreverá código como se fosse C++ com macros — ineficiente e doloroso.

\n\n

1. Iteradores e Closures

\n

Em Rust, iteradores não são apenas um loop for. São uma ferramenta funcional poderosa. Em vez de escrever for i in 0..vec.len(), aprenda a usar .iter(), .map(), .filter(), .fold().

\n\n
// Python: [x*2 for x in list if x > 0]\n// Rust:\nlet result: Vec<i32> = list.iter()\n    .filter(|&x| *x > 0)\n    .map(|x| x * 2)\n    .collect();
\n\n

Este código não é apenas mais curto, mas também funciona mais rápido, pois os iteradores são preguiçosos e o compilador os otimiza em um loop linear.

\n\n

2. HashMap e BTreeMap

\n

Para problemas de contagem de frequências (por exemplo, "Two Sum" ou "Group Anagrams"), HashMap é seu melhor amigo. Mas lembre-se: em Rust, inserir em um HashMap exige a propriedade da chave. Se você usar &str, precisará clonar a string ou usar String.

\n\n
use std::collections::HashMap;\n\nfn two_sum(nums: Vec<i32>, target: i32) -> Vec<i32> {\n    let mut map = HashMap::new();\n    for (i, &num) in nums.iter().enumerate() {\n        let complement = target - num;\n        if let Some(&j) = map.get(&complement) {\n            return vec![j as i32, i as i32];\n        }\n        map.insert(num, i);\n    }\n    vec![]\n}
\n\n

Observe: enumerate() retorna uma tupla (usize, &i32). Usamos &num para desreferenciar a referência.

\n\n

3. Vec e slices

\n

Vec é um array dinâmico. Mas nos problemas do LeetCode, muitas vezes é necessário trabalhar com subarrays. Para isso, use slices &[T]. Eles não exigem cópia e permitem passar parte do array para uma função.

\n\n
fn max_subarray_sum(arr: &[i32]) -> i32 {\n    let mut max_ending = arr[0];\n    let mut max_so_far = arr[0];\n    for &x in arr[1..].iter() {\n        max_ending = std::cmp::max(x, max_ending + x);\n        max_so_far = std::cmp::max(max_so_far, max_ending);\n    }\n    max_so_far\n}
\n\n

Top 5 erros típicos

Blogs

Book Recommendations