Big O notation basics for web developers
Tags: bigonotation
Published: 2021-02-11 17:53:12

<h2><b>Explain what Big O notation is and why web developers should know about it:</b></h2>

Big O notation is used in Computer Science to describe the performance or complexity of an algorithm. Big O specifically describes the worst-case scenario, and can be used to describe the execution time required or the space used (e.g. in memory or on disk) by an algorithm.

<h2><b>Explain what a quadratic function (O(n2)) is:</b></h2>

The complexity of an algorithm is said to be quadratic when the steps required to execute an algorithm are a quadratic function of the number of items in the input. Quadratic complexity is denoted as O(n^2).

<h2><b>Example of JavaScript code that is O(n2):</b></h2>

void printAllPossibleOrderedPairs(int arr[], int size)
{
    for (int i = 0; i < size; i++)
    {
        for (int j = 0; j < size; j++)
        {
            printf("%d = %d\n", arr[i], arr[j]);
        }
     }
}

Here we're nesting two loops. If our array has n items, our outer loop runs n times and our inner loop runs n times for each iteration of the outer loop, giving us n2 total prints. Thus this function runs in O(n2) time (or "quadratic time"). If the array has 10 items, we have to print 100 times. If it has 1000 items, we have to print 1000000 times.

<b><h2>Linear search</b></h2> looks down a list, one item at a time, without jumping. In complexity terms this is an O(n) search - the time taken to search the list gets bigger at the same rate as the list does.

<b><h2>Binary search</b></h2> is when you start with the middle of a sorted list, and see whether that's greater than or less than the value you're looking for, which determines whether the value is in the first or second half of the list. Jump to the half way through the sublist, and compare again etc. This is pretty much how humans typically look up a word in a dictionary (although we use better heuristics, obviously - if you're looking for "cat" you don't start off at "M"). In complexity terms this is an O(log n) search - the number of search operations grows more slowly than the list does, because you're halving the "search space" with each operation.

<b><h2>Compare a linear search with a binary search algorithm:</b></h2>

- Binary search requires the input data to be sorted; linear search doesn't

- Binary search requires an ordering comparison; linear search only requires equality comparisons

- Binary search has complexity O(log n); linear search has complexity O(n) as discussed earlier

<b><h2>Linear search algorithm code:</b></h2>

function linearSearch(arr, key){
    for(let i = 0; i < arr.length; i++){
        if(arr[i] === key){
            return i
        }
    }
    return -1
}

<b><h2>Binary search algorithm code:</b></h2>

function binarySearch(sortedArray, key){
    let start = 0;
    let end = sortedArray.length - 1;
    while (start <= end) {
        let middle = Math.floor((start + end) / 2);
        if (sortedArray[middle] === key) {
            // found the key
            return middle;
        } else if (sortedArray[middle] < key) {
            // continue searching to the right
            start = middle + 1;
        } else {
            // search searching to the left
            end = middle - 1;
        }
    }
    return -1;
}

<b><h2>Describe what the Fibonacci sequence is:</b></h2>

Fibonacci Sequence is the series of numbers: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... The next number is found by adding up the two numbers before it: the 2 is found by adding the two numbers before it (1+1), the 3 is found by adding the two numbers before it (1+2), the 5 is (2+3), and so on!


<b><h2>Fibonacci sequence using recursion:</b></h2>

function fibonacci(num) {
  if (num < 2) {
    return num;
  } else {
    return fibonacci(num - 1) + fibonacci(num - 2);
  }
}

if (5 <= 0) {
  console.log("Enter a positive integer.");
} else {
  for (let i = 0; i < 6; i++) {
    console.log(fibonacci(i));
  }
}

<b><h2>Code that write the first 5 numbers in the Fibonacci sequence using Loop:</b></h2>

let n1 = 0;
let n2 = 1;
next;

for (let i = 1; i <= 5; i++) {
  console.log(n1);
  nextTerm = n1 + n2;
  n1 = n2;
  n2 = next;
}



<b><h2>Which algorithm is the more efficient solution to the problem:</b></h2>

- A recursive function in general has an extremely high time complexity while a non-recursive one does not.

- A recursive function generally has smaller code size whereas a non-recursive one is larger.

Reference:

- https://www.upgrad.com/blog/linear-search-vs-binary-search/

- https://developerinsider.co/big-o-notation-explained-with-examples/

- https://www.mathsisfun.com/numbers/fibonacci-sequence.html

- https://www.programmingincpp.com/recursive-function-versus-non-recursive-function.html

- http://web.mit.edu/16.070/www/lecture/big_o.pdf