"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Introdução ao DSA e notação Big O

Introdução ao DSA e notação Big O

Publicado em 31/10/2024
Navegar:177

Intro to DSA & Big O Notation

Notas para dominar o DSA:

Master DSA será "elegível" para altos salários oferecidos aos S/w Ers.
DSA é a maior parte da Engenharia de Software.
Antes de escrever o código, certifique-se de entender o panorama geral e, em seguida, aprofunde-se nos detalhes.
É tudo uma questão de compreender os conceitos visualmente e, em seguida, traduzi-los em código por meio de qualquer l/g, já que o DSA é independente de linguagem.
Cada conceito futuro está de alguma forma ligado a conceitos anteriores. Portanto, não pule tópicos ou avance a menos que você tenha dominado completamente o conceito praticando-o.
Quando aprendemos conceitos visualmente, obtemos uma compreensão mais profunda do material, o que por sua vez nos ajuda a reter o conhecimento por mais tempo.
Se você seguir esses conselhos, não terá nada a perder.

Linear DS:
Arrays
LinkedList(LL) & Doubly LL (DLL)
Stack
Queue & Circular Queue

Non-linear DS:
Trees
Graphs

Notação O grande

É essencial entender esta notação para comparação de desempenho de algoritmos.
É uma forma matemática de comparar a eficiência de algoritmos.

Complexidade de tempo

Quanto mais rápido o código for executado, menor será
V. impacto na maioria das entrevistas.

Complexidade Espacial

Considerado raramente em comparação com a complexidade do tempo devido ao baixo custo de armazenamento.
Precisa ser entendido, pois um entrevistador também pode perguntar sobre isso.

Três letras gregas:

  1. Ómega
  2. Teta
  3. Omicron, ou seja, Big-O [visto com mais frequência]

Casos para algo

  1. Melhor caso [representado usando Omega]
  2. Caso médio [representado usando Theta]
  3. Pior caso [representado usando Omicron]

Tecnicamente, não existe o melhor caso do caso médio Big-O. Eles são denotados usando ômega e teta respectivamente.
Estamos sempre medindo o pior caso.

## O(n): Efficient Code
Proportional
Its simplified by dropping the constant values.
An operation happens 'n' times, where n is passed as an argument as shown below.
Always going to be a straight line having slope 1, as no of operations is proportional to n.
X axis - value of n.
Y axis - no of operations 

// O(n)
function printItems(n){
  for(let i=1; i





## O(n^2):
Nested loops.
No of items which are output in this case are n*n for a 'n' input.
function printItems(n){
  for(let i=0; i
## O(n^3):
No of items which are output in this case are n*n*n for a 'n' input.
// O(n*n*n)
function printItems(n){
  for(let i=0; i O(n*n)


## Drop non-dominants:
function xxx(){
  // O(n*n)
  Nested for loop

  // O(n)
  Single for loop
}
Complexity for the below code will O(n*n)   O(n) 
By dropping non-dominants, it will become O(n*n) 
As O(n) will be negligible as the n value grows. O(n*n) is dominant term, O(n) is non-dominnat term here.
## O(1):
Referred as Constant time i.e No of operations do not change as 'n' changes.
Single operation irrespective of no of operands.
MOST EFFICIENT. Nothing is more efficient than this. 
Its a flat line overlapping x-axis on graph.


// O(1)
function printItems(n){
  return n n n n;
}
printItems(3);


## Comparison of Time Complexity:
O(1) > O(n) > O(n*n)
## O(log n)
Divide and conquer technique.
Partitioning into halves until goal is achieved.

log(base2) of 8 = 3 i.e we are basically saying 2 to what power is 8. That power denotes the no of operations to get to the result.

Also, to put it in another way we can say how many times we need to divide 8 into halves(this makes base 2 for logarithmic operation) to get to the single resulting target item which is 3.

Ex. Amazing application is say for a 1,000,000,000 array size, how many times we need to cut to get to the target item.
log(base 2) 1,000,000,000 = 31 times
i.e 2^31 will make us reach the target item.

Hence, if we do the search in linear fashion then we need to scan for billion items in the array.
But if we use divide & conquer approach, we can find it in just 31 steps.
This is the immense power of O(log n)

## Comparison of Time Complexity:
O(1) > O(log n) > O(n) > O(n*n)
Best is O(1) or O(log n)
Acceptable is O(n)
O(n log n) : 
Used in some sorting Algos.
Most efficient sorting algo we can make unless we are sorting only nums.
Tricky Interview Ques: Different Terms for Inputs.
function printItems(a,b){
  // O(a)
  for(let i=0; i





## Arrays
No reindexing is required in arrays for push-pop operations. Hence both are O(1).
Adding-Removing from end in array is O(1)

Reindexing is required in arrays for shift-unshift operations. Hence, both are O(n) operations, where n is no of items in the array.
Adding-Removing from front in array is O(n)

Inserting anywhere in array except start and end positions:
myArr.splice(indexForOperation, itemsToBeRemoved, ContentTobeInsterted)
Remaining array after the items has to be reindexed.
Hence, it will be O(n) and not O(0.5 n) as Big-O always meassures worst case, and not avg case. 0.5 is constant, hence its droppped.
Same is applicable for removing an item from an array also as the items after it has to be reindexed.


Finding an item in an array:
if its by value: O(n)
if its by index: O(1)

Select a DS based on the use-case.
For index based, array will be a great choice.
If a lot of insertion-deletion is perform in the begin, then use some other DS as reindexing will make it slow.

Comparação da complexidade de tempo para n=100:

O(1) = 1
O(log 100) = 7
O(100) = 100
O (n ^ 2) = 10.000

Comparação da complexidade de tempo para n=1000:

O(1) = 1
O(log 1000) = ~10
O(1000) = 1000
O(1000*1000) = 1.000.000

Vamos nos concentrar principalmente nestes 4:
Grande O (n * n): Loops aninhados
Grande O(n): Proporcional
Big O (log n): Dividir e conquistar
Grande O(1): Constante

O(n!) geralmente acontece quando escrevemos deliberadamente um código incorreto.
O(n*n) é horrível Algo
O(n log n) é aceitável e usado por certos algoritmos de classificação
Sobre (n): Aceitável
O (log n), O (1): Melhor

A complexidade do espaço é quase a mesma para todos os DS, ou seja, O (n).
A complexidade do espaço irá variar de O(n) a O(log n) ou O(1) com algoritmos de classificação

A complexidade do tempo é o que varia com base no algoritmo

A melhor complexidade de tempo para classificação diferente de números como string é O (n log n), que está em classificações rápidas, mescladas, tempo e heap.

A melhor maneira de aplicar seu aprendizado é codificar o máximo que puder.

Selecionar qual DS escolher em qual declaração do problema com base nos prós e contras de cada DS.

Para mais informações, consulte: bigochheatsheet.com

Declaração de lançamento Este artigo foi reproduzido em: https://dev.to/mahf001/intro-to-dsa-big-o-notation-5gm9?1 Se houver alguma violação, entre em contato com [email protected] para excluí-la
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3