Skip to content

Commit cfbbb7b

Browse files
committed
created divide_and_conquer folder and added max_sub_array_sum.py under it (issue #817)
1 parent 3657aed commit cfbbb7b

File tree

3 files changed

+139
-74
lines changed

3 files changed

+139
-74
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
"""
2+
The algorithm finds distance between closest pair of points in the given n points.
3+
Approach: Divide and conquer
4+
The points are sorted based on x-cords
5+
& by applying divide and conquer approach,
6+
minimum distance is obtained recursively.
7+
8+
Edge case: closest points lie on different sides of partition
9+
This case handled by forming a strip of points
10+
which are at a distance (< closest_pair_dis) from mid-point.
11+
(It is a proven that strip contains at most 6 points)
12+
And brute force method is applied on strip to find closest points.
13+
14+
Time complexity: O(n * (logn) ^ 2)
15+
"""
16+
17+
18+
import math
19+
20+
21+
def euclidean_distance(point1, point2):
22+
return math.sqrt(pow(point1[0] - point2[0], 2) + pow(point1[1] - point2[1], 2))
23+
24+
25+
def column_based_sort(array, column = 0):
26+
return sorted(array, key = lambda x: x[column])
27+
28+
29+
#brute force approach to find distance between closest pair points
30+
def dis_btw_closest_pair(points, no_of_points, min_dis = float("inf")):
31+
for i in range(no_of_points - 1):
32+
for j in range(i+1, no_of_points):
33+
current_dis = euclidean_distance(points[i], points[j])
34+
if current_dis < min_dis:
35+
min_dis = current_dis
36+
return min_dis
37+
38+
39+
#divide and conquer approach
40+
def closest_pair_of_points(points, no_of_points):
41+
# base case
42+
if no_of_points <= 3:
43+
return dis_btw_closest_pair(points, no_of_points)
44+
45+
#recursion
46+
mid = no_of_points//2
47+
closest_in_left = closest_pair_of_points(points[:mid], mid)
48+
closest_in_right = closest_pair_of_points(points[mid:], no_of_points - mid)
49+
closest_pair_dis = min(closest_in_left, closest_in_right)
50+
51+
#points which are at a distance (< closest_pair_dis) from mid-point
52+
cross_strip = []
53+
for point in points:
54+
if abs(point[0] - points[mid][0]) < closest_pair_dis:
55+
cross_strip.append(point)
56+
57+
cross_strip = column_based_sort(cross_strip, 1)
58+
closest_in_strip = dis_btw_closest_pair(cross_strip,
59+
len(cross_strip), closest_pair_dis)
60+
return min(closest_pair_dis, closest_in_strip)
61+
62+
63+
points = [[2, 3], [12, 30], [40, 50], [5, 1], [12, 10]]
64+
points = column_based_sort(points)
65+
print("Distance:", closest_pair_of_points(points, len(points)))
66+
67+
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
"""
2+
Given a array of length n, max_sub_array_sum() finds the maximum of sum of contiguous sub-array using divide and conquer method.
3+
4+
Time complexity : O(n log n)
5+
6+
Ref : INTRODUCTION TO ALGORITHMS THIRD EDITION (section : 4, sub-section : 4.1, page : 70)
7+
8+
"""
9+
10+
11+
def max_sum_from_start(array):
12+
""" This function finds the maximum contiguous sum of array from 0 index
13+
14+
Parameters :
15+
array (list[int]) : given array
16+
17+
Returns :
18+
max_sum (int) : maximum contiguous sum of array from 0 index
19+
20+
"""
21+
array_sum = 0
22+
max_sum = float("-inf")
23+
for num in array:
24+
array_sum += num
25+
if array_sum > max_sum:
26+
max_sum = array_sum
27+
return max_sum
28+
29+
30+
def max_cross_array_sum(array, left, mid, right):
31+
""" This function finds the maximum contiguous sum of left and right arrays
32+
33+
Parameters :
34+
array, left, mid, right (list[int], int, int, int)
35+
36+
Returns :
37+
(int) : maximum of sum of contiguous sum of left and right arrays
38+
39+
"""
40+
41+
max_sum_of_left = max_sum_from_start(array[left:mid+1][::-1])
42+
max_sum_of_right = max_sum_from_start(array[mid+1: right+1])
43+
return max_sum_of_left + max_sum_of_right
44+
45+
46+
def max_sub_array_sum(array, left, right):
47+
""" This function finds the maximum of sum of contiguous sub-array using divide and conquer method
48+
49+
Parameters :
50+
array, left, right (list[int], int, int) : given array, current left index and current right index
51+
52+
Returns :
53+
int : maximum of sum of contiguous sub-array
54+
55+
"""
56+
57+
# base case: array has only one element
58+
if left == right:
59+
return array[right]
60+
61+
# Recursion
62+
mid = (left + right) // 2
63+
left_half_sum = max_sub_array_sum(array, left, mid)
64+
right_half_sum = max_sub_array_sum(array, mid + 1, right)
65+
cross_sum = max_cross_array_sum(array, left, mid, right)
66+
return max(left_half_sum, right_half_sum, cross_sum)
67+
68+
69+
array = [-2, -5, 6, -2, -3, 1, 5, -6]
70+
array_length = len(array)
71+
print("Maximum sum of contiguous subarray:", max_sub_array_sum(array, 0, array_length - 1))
72+

strings/Boyer_Moore_Search.py

Lines changed: 0 additions & 74 deletions
This file was deleted.

0 commit comments

Comments
 (0)