Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary...

29
Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide & Conquer 1 Contest Algorithms: 5. Divide & Conquer

Transcript of Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary...

Page 1: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

1

Contest AlgorithmsJanuary 2016

Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort).

5. Divide & Conquer

Contest Algorithms: 5. Divide & Conquer

Page 2: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

1. Divide-and-Conquer

1. Divide problem into two or more smaller instances

2. Solve smaller instances recursively (conquer)

3. Obtain solution to original (larger) problem by combining these solutions

Page 3: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Divide-and-Conquer Technique

solvesubproblem 2

of size n/2

a solution to subproblem 1

a solution tothe original problem

solve a problem of size n

a recursive algorithm

combine solutions

solvesubproblem 1

of size n/2

divide problem into smaller parts (often 2)

a solution to subproblem 2

Page 4: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Divide-and-Conquer Examples

Binary exponentiation Binary search Sorting: mergesort and quicksort

(see QuickSort.java)

Closest Pair of Points Problem see the Computational Geometry slides

Page 5: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

5

2. Binary Exponentiation : xn

public static long pow(long x, long n) { if (n <= 0) // n must be positive return 1; else if (n % 2 == 1) { // odd long p = pow(x, (n-1)/2); // pow of x faster than x2

return x * p * p; } else { // n even long p = pow(x, n/2); return p * p; } } // end of pow()

see Power.java

Page 6: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Contest Algorithms: 4. Backtracking

6

Java interprets all numeral literals as 32-bit integers. e.g. long x = 30000000;

// will give "integer number too large" error

int range: -2147483648 to 2147483647 (231-1)

If you want to write something bigger than a 32-bit integer, use the suffix L:

e.g. long x = 30000000L; // accepted

Writing long numbers

Page 7: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Contest Algorithms: 4. Backtracking

7

public static void main (String[] args){ System.out.println("5^2 = " + pow(5,2)); System.out.println("2^10 = " + pow(2,10));

for (int i=10; i <= 100; i=i+5) System.out.println("2^" + i + " = " + pow(2,i));} // end of main()

Using pow()

Page 8: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Contest Algorithms: 4. Backtracking

8

Problems with overflow: Three ways to solve it

write youe own multiply() use Math.multiplyExact()

in Java 8 use BigInteger

see "Maths" slides BigInteger.pow(int

exponent)

Page 9: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Contest Algorithms: 4. Backtracking

9

public static long mult(long a, long b) { if ((a != 0) && (b > Long.MAX_VALUE / a)) // detect overflow System.out.println("Overflow for a*b:\n " + a + " * " + b); return a*b; }

In pow(), replace the three uses of "*": return mult(x, mult(p, p)); // was x * p * p return mult(p, p); // was p * p

Your own multiply()

Page 10: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Contest Algorithms: 4. Backtracking

10

Page 11: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Contest Algorithms: 4. Backtracking

11

In pow(), replace the three uses of "*":

return Math.multiplyExact(x, Math.multiplyExact(p,p)); // was x * p * p

return Math.multiplyExact(p, p); // was p * p

Use Math.multiplyExact()

Page 12: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Contest Algorithms: 4. Backtracking

12

Page 13: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Contest Algorithms: 4. Backtracking

13

addExact(), subtractExact(), multiplyExact() incrementExact(), decrementExact() toIntExact()

used when casting a long to an int

Instead of silently giving the wrong answer, they will throw a java.lang.ArithmeticException for overflows involving int or long calculations

Java 8 "Exact" Math methods

Page 14: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Binary Search is a divide and conquer algorithm.

Find an element in a sorted array:1. Divide: Check middle element.2. Conquer: Recursively search 1 subarray.3. Combine: Easy; return index

3. Binary Search

Example: Find 9

3 5 7 8 9 12 15

As implemented in Java byArrays.binarySearch()

Page 15: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Example

Example: Find 9

3 5 7 8 9 12 15

Find an element in a sorted array:

1.Divide: Check middle element.2.Conquer: Recursively search 1

subarray.3.Combine: Trivial.

Page 16: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Example: Find 9

3 5 7 8 9 12 15

Find an element in a sorted array:

1.Divide: Check middle element.2.Conquer: Recursively search 1

subarray.3.Combine: Trivial.

Page 17: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Example: Find 9

3 5 7 8 9 12 15

Find an element in a sorted array:

1.Divide: Check middle element.2.Conquer: Recursively search 1

subarray.3.Combine: Trivial.

Page 18: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Example: Find 9

3 5 7 8 9 12 15

Find an element in a sorted array:

1.Divide: Check middle element.2.Conquer: Recursively search 1

subarray.3.Combine: Trivial.

Page 19: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Find an element in a sorted array:

1.Divide: Check middle element.2.Conquer: Recursively search 1

subarray.3.Combine: Trivial.

Example: Find 9

3 5 7 8 9 12 15

Page 20: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Binary Search Code private static int binarySearch(int[] arr, int val) { return binSrch(arr, val, 0, arr.length-1); }

private static int binSrch(int[] arr, int val, int start, int end) { if (start > end) // val not found return -1;

int middle = (start + end)/2; int midVal = arr[middle]; if (val == midVal) return middle; else if (val > midVal) // search right half return binSrch(arr, val, middle+1, end); else // search left half return binSrch(arr, val, start, middle-1); } // end of binSrch()

see BinarySearchTest.java

Page 21: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Contest Algorithms: 4. Backtracking

21

public static void main (String[] args){ Integer[] intArr = {2, 3, 5, 7, 9, 10, 13, 15, 17, 19}; System.out.println("Index pos of 10: " +

Arrays.binarySearch(intArr, 10)); System.out.println("Index pos of 22: " +

Arrays.binarySearch(intArr, 22)); int[] arr = {2, 3, 5, 7, 9, 10, 13, 15, 17, 19}; System.out.println("Index pos of 10: " + binarySearch(arr, 10)); System.out.println("Index pos of 22: " + binarySearch(arr, 22));} // end of main()

Using Both Functions

Index pos of 10: 5Index pos of 22: -11Index pos of 10: 5Index pos of 22: -1

Page 22: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

22

4. Mergesort

A stable sorting algorithm with worst-case running time O(n log n)

Algorithm: Divide the list into two sub-lists Sort each sub-list (recursion) Merge the two sorted sub-lists

Page 23: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

23

Codepublic static void mergeSort(int[] arr){ int[] temp = new int[arr.length]; msort(arr, temp, 0, arr.length);}

private static void msort(int[] arr, int[] temp, int left, int right){ // continue only if the sub-array has more than 1 element if ((left + 1) < right) { int mid = (right + left)/2; msort(arr, temp, left, mid); msort(arr, temp, mid, right); merge(arr, temp, left, mid, right); }} // end of msort()

O(n)

see MergeSort.java

Page 24: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

merge

Tracing msort()

Page 25: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Merging two sorted arrays

20

13

7

2

12

11

9

1

1

20

13

7

2

12

11

9

2

20

13

7

12

11

9

7

20

13

12

11

9

9

20

13

12

11

11

20

13

12

12

Time = one pass through each array = O(n) to merge a total of n elements (linear time).

Page 26: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

private static void merge(int[] arr, int[] temp, int left, int mid, int right) { // are the two sub-arrays already in sorted order? if (arr[mid-1] <= arr[mid]) return;

int indexA = left; // to scan 1st sub-array int indexB = mid; // to scan 2nd sub-array int i = left; // for moving over temp array

// compare arr[indexA] and arr[indexB]; copy the smaller to temp while ((indexA < mid) && (indexB < right)) { if (arr[indexA] < arr[indexB]) temp[i++] = arr[indexA++]; // copy and move idxs else temp[i++] = arr[indexB++]; } :

Page 27: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Contest Algorithms: 4. Backtracking

39

: // copy the tail of the sub-array that is not finished while (indexA < mid) temp[i++] = arr[indexA++];

while (indexB < right) temp[i++] = arr[indexB++];

// copy from temp back to arr for (int j = left; j < right; j++) arr[j] = temp[j]; } // end of merge()

Page 28: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Contest Algorithms: 4. Backtracking

40

public static void main (String[] args){ int[] arr = {18, 3, 5, 23, 4, 17, 2, 16, 19}; System.out.println("Unsorted array: " + Arrays.toString(arr));

mergeSort(arr); System.out.println("Sorted array: " + Arrays.toString(arr));

Integer[] intArr = {18, 3, 5, 23, 4, 17, 2, 16, 19}; Arrays.sort(intArr); // quicksort System.out.println("Sorted array: " + Arrays.toString(intArr));} // end of main()

Using Two Sorts

Page 29: Contest Algorithms January 2016 Pseudo-code for divide and conquer, and three examples (binary exponentiation, binary search, and mergesort). 5. Divide.

Contest Algorithms: 4. Backtracking

41