1 / 13

Efficient Counting Inversions Algorithm Using Divide and Conquer

Learn how to efficiently count inversions in an array using a Divide and Conquer approach with a step-by-step example. Explore the concept of merging and counting to achieve a faster algorithm. Master the application of the Divide and Conquer technique, including the Master Theorem for recursion analysis.

pclancy
Download Presentation

Efficient Counting Inversions Algorithm Using Divide and Conquer

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Lecture 3: Divide and Conquer

  2. Example 2 Counting Inversions • Goal: Given array a[], count the number of pairs (i,j) such that i < j but a[i] > a[j]. • Input: Array a[] = {6, 2, 4, 1, 5, 3, 7, 8} • Answer = 9

  3. How to count inversions more efficiently? • b[] = {6, 2, 4, 1}, 5 inversionsc[] = {5, 3, 7, 8}, 1 inversion • For each number in b, want to know how many numbers in c are smaller.6: 2, 2: 0, 4: 1, 1: 0, result = 2+0+1+0 = 3. • Much easier if c[] is sorted! • Idea: Can sort the arrays when we are counting inversions.

  4. Sort&Count Sort&Count(a[]) IF Length(a) < 2 THENRETURN (a[], 0). (Base Case) Partition a[] evenly into two arrays b[], c[]. (Divide) (b[], count_b) = Sort&Count(b[]) (c[], count_c) = Sort&Count(c[]) (Conquer) (a[], count_bc) = Merge&Count(b[], c[]). (Merge) RETURN a[], count_b+count_c+count_bc.

  5. Merge&Count • b[] = {1, 2, 4, 6} c[] = {3, 5, 7, 8} • {1, 2, 3, 4, 5, 6, 7, 8} • When 4 goes into the array, pointer in c[] is pointing at 5 (2nd element), so 4 is larger than 1 element in c[]. • When 6 goes into the array, pointer in c[] is pointing at 7 (3rd element), so 6 is larger than 2 elements in c[].

  6. Merge&Count Merge&Count(b[], c[]) a[] = empty i = 1, j = 1 count = 0 WHILEi <= Length(b[]) OR j <= Length(c[]) IF b[i] < c[j] THEN a.append(b[i]); i = i+1 count = count + (j - 1) ELSE a.append(c[j]); j = j+1 RETURN a[], count The i-th element of a[] is smaller than c[j], but larger than c[1,2,…, j-1]

  7. Running Time • Merging still take O(n) time, so we still have • T(n) = 2T(n/2) + A n for some constant A > 0 •  T(n) = O(n log n)

  8. Example 3 Integer Multiplication • Input: two positive integers a, b • Output: a×b • What if a = 73489553479834257983745 andb = 197878967893267834267324789? • Naïve algorithm: O(n2) time (learned in elementary school) ? multiply(a, b) RETURN a*b

  9. Divide and Conquer • a = 123,456 b = 654,321 • How to divide? • Write a = 123,000 + 456, b = 654,000 + 321. • Thena*b = 123*654*106 + (123*321+456*654)*103 + 456*321.

  10. First attempt • Partition a = a1*10n/2+a2, b = b1*10n/2+b2 • Recursively compute A = a1*a2, B = a2*b1, C = a1*b2, D = a2*b2 • Output A*10n+(B+C)*10n/2+D Multiply(a, b) (wlog assume n = length(a) = length(b), pad 0 for the shorter number) IF Length(a) <= 1 THENRETURN a*b Partition a into a = a1 * 10n/2+a2, b = b1*10n/2+b2 A = Multiply(a1, b1) B = Multiply(a2, b1) C = Multiply(a1, b2) D = Multiply(a2, b2) RETURN A*10n+(B+C)*10n/2 + D Need an algorithm for adding long numbers. Standard algorithm suffices (O(n))

  11. Improving the algorithm To make a divide and conquer algorithm faster • Make the merging step faster • Make the sub-problems smaller • Reduce the number of sub-problems • Observation:(a1*b2+a2*b1) = (a1+a2)*(b1+b2) – a1*b1 – a2*b2

  12. Improved Algorithm • Partition a = a1*10n/2+a2, b = b1*10n/2+b2 • Recursively compute A = a1*b1, B = a2*b2, C = (a1+a2)*(b1+b2) • Output A*10n+(C-A-B)*10n/2+B Multiply(a, b) (wlog assume n = length(a) = length(b), pad 0 for the shorter number) IF Length(a) <= 1 THENRETURN a*b Partition a into a = a1 * 10n/2+a2, b = b1*10n/2+b2 A = Multiply(a1, b1) B = Multiply(a2, b2) C = Multiply(a1+a2, b1+b2) RETURN A*10n+(C-A-B)*10n/2 + B

  13. Master Theorem • “Cheat sheet” for simple recursions • Theorem: If T(n) = aT(n/b) + f(n), then • 1. If f(n) = O(nc), c < logba • 2. If f(n) = θ(nclogtn), c = logba • 3. If f(n) = θ(nc), c > logba

More Related