Entendendo algoritmos

Algoritmos da computação na sua jornada dev

Data de publicação: 25/02/2024 00:57

Última atualização: 09/03/2024 15:36

Principais conceitos de computação demonstrados no livro Entendendo algoritmos:


Capítulo 1 - Introdução a algoritmos

  • A pesquisa binária é muito mais rápida do que a pesquisa simples.
  • O(log n) é mais rápido do que O(n) e O(log n) fica ainda mais rápido conforme os elementos da lista aumentam.
  • A rapidez de um algoritmo não é medida em segundos.
  • O tempo de execução de um algoritmo é medido por meio de seu crescimento.
  • O tempo de execução dos algoritmos é expresso na notação Big O.


Capítulo 2 - Ordenação por seleção

  • A memória do seu computador é como um conjunto gigante de gavetas.
  • Quando se quer armazenar múltiplos elementos, usa-se um array ou uma lista.
  • No array, todos os elementos são armazenados um ao lado do outro.
  • Na lista, os elementos estão espalhados e um elemento armazena o endereço do próximo elemento.
  • Arrays permitem leituras rápidas.
  • Listas encadeadas permitem rápidas inserções e eliminações.
  • Todos os elementos de um array devem ser do mesmo tipo (todos ints, todos doubles, e assim por diante).


Capítulo 3 - Recursão

  • Recursão é quando uma função chama a si mesma.
  • Toda função recursiva tem dois casos: o caso-base e o caso recursivo.
  • Uma pilha tem duas operações: push e pop.
  • Todas as chamadas de função vão para a pilha de chamada.
  • A pilha de chamada pode ficar muito grande e ocupar muita memória.


Capítulo 4 - Quicksort

  • A estratégia DC (Dividir para Conquistar) funciona por meio da divisão do problema em problemas menores. Se você estiver utilizando DC em uma lista, o caso-base provavelmente será um array vazio ou um array com apenas um elemento.
  • Se você estiver implementando o quicksort, escolha um elemento aleatório como o pivô. O tempo de execução médio do quicksort é O(n log n)!
  • A constante, na notação Big O, pode ser relevante em alguns casos. Está é a ração pela qual o quicksort é mais rápido do que o merge sort.
  • A constante dificilmente será relevante na comparação entre pesquisa simples e pesquisa binária, pois O(log n) é muito mais rápido do que O(n) quando sua lista é grande.


Capítulo 5 - Tabelas hash

  • Você pode fazer uma tabela hash ao combinar uma função hash com um array.
  • Colisões são problemas. É necessário haver uma função hash que minimize colisões.
  • As tabelas hash são extremamente rápidas para pesquisar, inserir e remover itens.
  • Tabelas hash são boas para modelar relações entre dois itens.
  • Se o seu fator de carga for maior que 0.7, será necessário redimensionar a sua tabela hash.
  • As tabelas hash são utilizadas como cache de dados (como em um servidor da web, por exemplo).
  • Tabelas hash são ótimas para localizar duplicatas.


Capítulo 6 - Pesquisa em largura

  • A pesquisa em largura lhe diz se há um caminho de A para B.
  • Se esse caminho existir, a pesquisa em largura lhe dará o caminho mínimo.
  • Se você tem um problema do tipo “encontre o menor X”, tente modelar o seu problema utilizando grafos e use a pesquisa em largura para resolvê-lo.
  • Um dígrafo contem setas e as relações seguem a direção das setas (Rama → Adit significa “Rama deve dinheiro a Adit).
  • Grafos não direcionados não contêm setas, e a relação acontece nos dois sentidos (Ross - Rachel significa “Ross namorou Rachel e Rachel namorou Ross”).
  • Filas são FIFO (primeiro a entrar, primeiro a sair).
  • Pilhas são LIFO (último a entrar, primeiro a sair).
  • Você precisa verificar as pessoas na ordem em que elas foram adicionadas a lista de pesquisa. Portanto a lista de pesquisa deve ser uma fila; caso contrário, você não obterá o caminho mínimo.
  • Cada vez que você precisar verificar alguém, procure não verificá-lo novamente. Caso contrário, poderá acabar em um loop infinito.


Capítulo 7 - Algoritmo de Dijkstra

  • A pesquisa em largura é usada para calcular o caminho mínimo para um grafo não ponderado.
  • O algoritmo de Dijkstra é usado para calcular o caminho mínimo para um grafo ponderado.
  • O algoritmo de Dijkstra funciona quando todos os pesos são positivos.
  • Se o seu grafo tiver pesos negativos, use o algoritmo de Bellman-Ford.


Capítulo 8 - Algoritmos gulosos

  • Algoritmos gulosos otimizam localmente na esperança de acabar em uma otimização global.
  • Problemas NP-completo não tem uma solução rápida.
  • Se você estiver tentando resolver um problema NP-completo, o melhor a se fazer é usar um algoritmo de aproximação.
  • Algoritmos gulosos são fáceis de escrever e têm tempo de execução baixo, portanto eles são bons algoritmos de aproximação.


Capítulo 9 - Programação dinâmica

  • A programação dinâmica é útil quando você está tentando otimizar algo em relação a um limite.
  • Você pode utilizar a programação dinâmica quando o problema puder ser dividido em subproblemas discretos.
  • Os valores nas células são, geralmente, o que você está tentando otimizar.
  • Cada célula é um subproblema, então pense sobre como é possível dividir este subproblema em outros subproblemas.
  • Não existe uma fórmula única para calcular uma solução em programação dinâmica.


Capítulo 10 - K-vizinhos mais próximos

  • O algoritmo dos k-vizinhos mais próximos é utilizado na classificação e também na regressão. Ele envolve observar os K-vizinhos mais próximos.
  • Classificação = classificar em grupos.
  • Regressão - adivinhas uma resposta (como um número).
  • Extrair características significa converter um item (como uma fruta ou um usuário) em uma lista de números que podem ser comparados.
  • Escolher boas características é uma parte importante para que um algoritmos dos k-vizinhos mais próximos opere corretamente.