1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ # max_sum_dac solves the max-sum-subarray-problem with Divide and Conquer
5
+ # in O(m*log(m))
6
+
7
+ # example 1: max_sum_dac( [3,-5,0,2,100,-2,-5,9] )
8
+ # max-sum-subarray: [2,100,-2,-5,9]
9
+ # max-sum: 2+100-2-5+9 = 104
10
+
11
+ # example 2: max_sum_dac( [-3,5,-1,2,-5,3] )
12
+ # max-sum-subarray: [5,-1,2]
13
+ # max-sum: 5-1+2 = 6
14
+
15
+ def max_prefix_sum (a ):
16
+ i = 0
17
+ accumulator , maxval = a [i ], a [i ]
18
+
19
+ for j in range (1 ,len (a )):
20
+ accumulator += a [j ]
21
+ maxval = max (maxval , accumulator )
22
+ return maxval
23
+
24
+ def max_sum_dac (a ):
25
+ m = len (a )
26
+
27
+ # trivial case
28
+ if m == 1 :
29
+ return a [0 ]
30
+
31
+ # divide
32
+ a1 = a [:len (a )// 2 ]
33
+ a2 = a [len (a1 ):]
34
+
35
+ # recursion
36
+ l = max_sum_dac (a1 )
37
+ r = max_sum_dac (a2 )
38
+
39
+ # conquer
40
+ left_max = max_prefix_sum ([a1 [i ] for i in range (len (a1 )- 1 , - 1 , - 1 )]) #reversed a1
41
+ right_max = max_prefix_sum (a2 )
42
+ max_sum_over_middle = left_max + right_max
43
+ return max (max_sum_over_middle , l , r )
44
+
45
+ # Tests
46
+ print ("Tests:" )
47
+ a = [3 ,- 5 ,0 ,2 ,100 ,- 2 ,- 5 ,9 ]
48
+ print (max_sum_dac (a ) == 104 )
49
+ a = [- 3 ,5 ,- 1 ,2 ,- 5 ,3 ]
50
+ print (max_sum_dac (a ) == 6 )
51
+ a = [13 ,- 5 ,- 1 ,7 ,- 5 ,4 ]
52
+ print (max_sum_dac (a ) == 14 )
53
+ a = [3 ,- 5 ,0 ,1 ,10 ,- 2 ,- 5 ,6 ]
54
+ print (max_sum_dac (a ) == 11 )
55
+ a = [3 ,- 5 ,0 ,1 ,0 ,- 2 ,- 5 ,6 ]
56
+ print (max_sum_dac (a ) == 6 )
57
+ a = [- 3 ,- 9 ,- 4 ,- 5 ,- 2 ,- 1 ]
58
+ print (max_sum_dac (a ) == - 1 )
59
+ a = [3 ,5 ,10 ,9 ,2 ,3 ]
60
+ print (max_sum_dac (a ) == 32 )
61
+ a = [3 ,- 5 ,- 10 ,- 9 ,- 2 ,- 3 ]
62
+ print (max_sum_dac (a ) == 3 )
63
+ a = [3 ,- 5 ,10 ,9 ,- 2 ,- 3 ]
64
+ print (max_sum_dac (a ) == 19 )
0 commit comments