diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9b38853 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "python.testing.pytestArgs": [ + "tests" + ], + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true +} \ No newline at end of file diff --git a/lib/max_subarray.py b/lib/max_subarray.py index 4e892e0..20f6eef 100644 --- a/lib/max_subarray.py +++ b/lib/max_subarray.py @@ -1,12 +1,60 @@ +import sys -def max_sub_array(nums): +#To find the max sum of sub_array which includes values from left, mid and right of the nums array +def max_mid_array(nums, left, mid, right): + + # To find the max sum of the left, iterate backwards + #from the mid num + sum = 0 + left_sum = -sys.maxsize + + for i in range(mid, left-1, -1): + sum = sum + nums[i] + + if (sum > left_sum): + left_sum = sum + + #To find the max sum of right subarray iterate up(increasing index values)from the + #num to the right of mid num(mid + 1). + sum = 0 + right_sum = -sys.maxsize + + for i in range(mid + 1, right + 1): + sum = sum + nums[i] + + if (sum > right_sum): + right_sum = sum + + return (left_sum + right_sum) + +#To find the max subarray +def max_sub_array(nums, left=0, right=None): """ Returns the max subarray of the given list of numbers. Returns 0 if nums is None or an empty list. - Time Complexity: ? - Space Complexity: ? + + Time Complexity: Time complexity is O(nLogn) time because of the implementation of a Divide and Conquer approach, in which the max subarray of + the given array is found through comparing the left and right value of a recursively calculated mid-point. This method also recursively calls the + helper method; max_mid_array() which considers max subarrays that range from left to right across the mid-point, with an O(nLogn) time complexity. + + Space Complexity: Space complexity should be O(nLogn) as well because, according to my research, space complexity is relative to the size of the + call stack, which decreases by 2 values with each recursive call. """ - if nums == None: - return 0 - if len(nums) == 0: + n = len(nums) + + if n == 0: return 0 - pass + + if right == None: + right = n-1 + + #base case == only one element + if(left == right): + return nums[left] + + mid = (left + right) // 2 + + maximum_sum_left_subarray = max_sub_array(nums, left, mid) + maximum_sum_right_subarray = max_sub_array(nums, left+1, right) + maximum_sum_crossing_subarray = max_mid_array(nums, left, mid, right); + + return max(maximum_sum_left_subarray, maximum_sum_right_subarray, maximum_sum_crossing_subarray) diff --git a/lib/newman_conway.py b/lib/newman_conway.py index 70a3353..27d6cad 100644 --- a/lib/newman_conway.py +++ b/lib/newman_conway.py @@ -1,10 +1,29 @@ - -# Time complexity: ? -# Space Complexity: ? def newman_conway(num): """ Returns a list of the Newman Conway numbers for the given value. - Time Complexity: ? - Space Complexity: ? + Time Complexity: O(n) because the number of calculations performed depends on the size of num. + + Space Complexity: Space complexity is also O(n) becuase newman_conway_nums array to store sequence values, + nm_sequence_without_leading_zero to store result with leading 0 removed and result a array to which the properly + formatted result is saved are created and the amount of space that they occupy will depend on the size of the given num. """ - pass + if num == 0: + raise ValueError + + if num == 1: + return '1' + + if num == 2: + return '1 1' + + #array to store sequence values and provide starting values + newman_conway_nums = [0, 1, 1] + + for i in range(3, num + 1): + newman_conway_nums.append(newman_conway_nums[newman_conway_nums[i-1]] + newman_conway_nums[i-newman_conway_nums[i-1]]) + + nm_sequence_without_leading_zero = [str(num) for num in newman_conway_nums if num != 0] + result = " ".join(nm_sequence_without_leading_zero) + + return result + diff --git a/tests/test_max_sub_array.py b/tests/test_max_sub_array.py index cbfb249..4b564a8 100644 --- a/tests/test_max_sub_array.py +++ b/tests/test_max_sub_array.py @@ -1,11 +1,13 @@ from lib.max_subarray import max_sub_array def test_max_subarray_on_empty_array(): + assert max_sub_array([]) == 0 def test_max_subarray_with_negative_elements(): # Arrange input = [-3, -4, -5, -6, -7] + n = len(input) # Act answer = max_sub_array(input) @@ -16,6 +18,7 @@ def test_max_subarray_with_negative_elements(): def test_max_subarray_with_negative_array_with_largest_element_at_rear(): # Arrange input = [-4, -5, -6, -7, -1] + n = len(input) # Act answer = max_sub_array(input) @@ -26,6 +29,7 @@ def test_max_subarray_with_negative_array_with_largest_element_at_rear(): def test_max_subarray_with_one_element_array(): # Arrange input = [3] + n = len(input) # Act answer = max_sub_array(input) @@ -36,6 +40,7 @@ def test_max_subarray_with_one_element_array(): def test_max_sub_array_with_50_neg_50_50(): # Arrange input = [50, -50, 50] + n = len(input) # Act answer = max_sub_array(input) @@ -46,6 +51,7 @@ def test_max_sub_array_with_50_neg_50_50(): def test_max_sub_array_with_50_3_neg_50_3(): # Arrange input = [50, 3, -50, 50, 3] + n = len(input) # Act answer = max_sub_array(input) @@ -54,11 +60,13 @@ def test_max_sub_array_with_50_3_neg_50_3(): assert answer == 56 def test_max_sub_array_with_50_3_neg_50_10_65_neg_3(): - # Arrange + # Arrange input = [50, 3, -50, 10, 65, -3] + n = len(input) # Act answer = max_sub_array(input) # Assert assert answer == 78 # 50, 3, -50, 10, 65 (largest subarray) + \ No newline at end of file