Eduardo Quintana
Fullstack Developer @Nearsoft
Basically it's a set of well defined rules for solving computational problems.
Sorting
Compute the shortest route
Can we do better?
Language by which any computer programmers or computer scientists discuss the high level performance of computer algorithms.
"The running time of this sorting algorithm is O(n²)"
The approximate worst-case scenario of doing something
public boolean findItemInList(int toCheck, int[] numbers) {
for (int number : numbers) {
if (toCheck == number) {
return true;
}
}
return false;
}
findItemInList(1, [1,2,3]); ???
1 iteration
findItemInList(4, [1,2,3]); ???
3 iterations
worst-case = array.length iterations = n
O(n)
Function: 2n² + 2n
2n² + 2n
Remove constants
Remove lower order terms
n² + n
n² + n
=
=
n²
public boolean findNumber(int numberToFind, int[] numbers) {
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] == numberToFind) {
return true;
}
}
return false;
}
For a given array [1,2,3,4,5,6] what would be the running time algorithm of this code?
Assuming the array length is "n" then the running time algorithm of this code is "n" itself.
O(n)
public boolean findNumber2(int numToFind, int[] firstArray, int[] secondArray) {
//We are assuming both arrays have the same length in this example
for (int i = 0; i < firstArray.length; i++) {
if (firstArray[i] == numToFind) {
return true;
}
}
for (int i = 0; i < secondArray.length; i++) {
if (secondArray[i] == numToFind) {
return true;
}
}
return false;
}
We iterate over "n" twice
=
2n
2n
O(n)
public static List<String> allCombinations(int[] items) {
List<String> combinations = new ArrayList<>();
for (int i = 0; i < items.length; i++) {
for (int j = 0; j < items.length; j++) {
combinations.add("(" + items[i] + "," + items[j] + ")");
}
}
return combinations;
}
For each "n" iteration we iterate over all the items in "n" again (n x n) = n²
O(n²)
Input:
[1,2,3]
Output:
(1,1), (1,2), (1,3), (2,1), (2,2), ...
[3,5,1,6,7,0,4]
[3,5,1]
[6,7,0,4]
array of length "n"
[3]
[5,1]
[5]
[1]
[6,7]
[0,4]
[6]
[7]
[0]
[4]
Merge
[1,5]
Merge
[3]
[1,3,5]
, [1,5]
The problem:
Handle edge cases
sort an array of numbers.
public static int[] mergeSort(int[] list) {
if (list.length <= 1) {
return list;
}
Input:
[3]
Output:
[3]
Divide:
Array into 2 sub problems
public static int[] mergeSort(int[] list) {
/**
* Code from previous slide
*/
int[] first = new int[list.length/2];
int[] second = new int[list.length - first.length];
System.arraycopy(list, 0, first, 0, first.length);
System.arraycopy(list, first.length, second, 0, second.length);
Input:
[5,3,6,7,1]
first = [5,3]
second = [6,7,1]
Process subproblems with recursion
public static int[] mergeSort(int[] list) {
/**
* Code from previous slide
*/
mergeSort(first); // [5,3]
mergeSort(second); //[6,7,1]
First recursion from first subproblem
public static int[] mergeSort(int[] list) {
/**
* list = [5,3]
* first = [5]
* second = [3]
*/
mergeSort(first); //[5] if we remember edge cases
mergeSort(second); //[3] when array has length 1 return the same list;
//merge([5], [3], [5,3])
merge(first, second, list);
return list;
}
Merge solutions
private static void merge(int[] first, int[] second, int[] result) {
//Merges both sorted arrays into the resulting array
int iFirst = 0;
int iSecond = 0;
int j = 0;
//Iterate over the length of both arrays checking which number is larger
while (iFirst < first.length && iSecond < second.length) {
if (first[iFirst] < second[iSecond]) {
result[j] = first[iFirst++];
} else {
result[j] = second[iSecond++];
}
j++;
}
//Copy missing numbers
//arraycopy(Object src, int srcPos,
// Object dest, int destPos, int length)
System.arraycopy(first, iFirst, result, j, first.length - iFirst);
System.arraycopy(second, iSecond, result, j, second.length - iSecond);
}
Continue second part recursion
public static int[] mergeSort(int[] list) {
/**
* Code from previous slide
*/
mergeSort(first); // [5,3] => [3,5]
//[6,7,1] => [6] , [7,1] ([7][1]) first recursion [6], [1,7] => [1,6,7]
mergeSort(second);
//merge([3,5], [1,6,7] , [5,3,6,7,1])
merge(first,second,list);
return list;
}
O(n log2 n)
For each individual problem we execute at most 6 instructions (we are not including edge cases).
6n operations
We have at most (log2 n + 1)
6n( log2n + 1) = 6n log2 n + 6n
Problem:
Determine if two words are anagrams
Anagram:
a type of word play, the result of rearranging the letters of a word or phrase to produce a new word or phrase, using all the original letters the same number of times.
Input:
("mary","army")
Output:
true
https://github.com/eddiarnoldo/algorithms