diff --git a/README.md b/README.md index cb70688..af5c831 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,66 @@ -# Dynamic Programming Based on the Ruby version from [AdaGold/dynamic-programming](https://github.com/Ada-C12/dynamic-programming). ## Running To run this repo, clone and install it, then run tests with `npm run test`. + +# Dynamic Programming + +Dynamic programming is a strategy for developing an algorithm where each subproblem is solved and the results recorded for use in solving larger problems. In this exercise you will write a pair of dynamic programming methods. + +## Wave 1 Newman-Conway Sequence + +[Newman-Conway sequence] is the one which generates the following integer sequence. 1 1 2 2 3 4 4 4 5 6 7 7….. and follows below recursive formula. + +``` +P(1) = 1 +P(2) = 1 +for all n > 2 +P(n) = P(P(n - 1)) + P(n - P(n - 1)) +``` + +Given a number n then print n terms of Newman-Conway Sequence + +Examples: + +``` +Input : 13 +Output : 1 1 2 2 3 4 4 4 5 6 7 7 8 + +Input : 20 +Output : 1 1 2 2 3 4 4 4 5 6 7 7 8 8 8 8 9 10 11 12 +``` + +You should be able to do this in O(n) time complexity. + +## Wave 2 Largest Sum Contiguous Subarray + +Write a method to find the contiguous subarray in a 1-dimensional array with the largest sum. + +![Largest subarray](images/kadane-Algorithm.png) + +This can be solved using Kadane's Algorithm + +``` +Initialize: + max_so_far = 0 + max_ending_here = 0 + +Loop for each element of the array + (a) max_ending_here = max_ending_here + a[i] + (b) if(max_ending_here < 0) + max_ending_here = 0 + (c) if(max_so_far < max_ending_here) + max_so_far = max_ending_here +return max_so_far +``` + +### Explanation + +The idea of the Kadane’s algorithm is to look for all positive contiguous segments of the array (max_ending_here is used for this). And keep track of the maximum sum contiguous segment among all positive segments (max_so_far is used for this). Each time we get a positive sum compare it with max_so_far and update max_so_far if it is greater than max_so_far + +There is also a subtle divide & conquer algorithm for this. + +## Sources + +- [GeeksforGeeks: Newman-Conway Sequence](https://www.geeksforgeeks.org/newman-conway-sequence/) +- [GeeksforGeeks: Largest Sum Contiguous Subarray](https://www.geeksforgeeks.org/largest-sum-contiguous-subarray/) diff --git a/lib/max_subarray.js b/lib/max_subarray.js index 46c166f..302e88c 100644 --- a/lib/max_subarray.js +++ b/lib/max_subarray.js @@ -1,9 +1,28 @@ -// Time Complexity: -// Space Complexity: +// Time Complexity: O(n) - we iterate n times through nums, which is an array of length n +// Space Complexity: O(1) - we have constant space complexity, with variables max_result and temp_max function maxSubArray(nums) { - throw new Error("Function not implemented yet...") + if (nums.length < 1) { + return null; + } + + let max_result = -Infinity, + temp_max = 0; + + for (let i = 0; i < nums.length; i++) { + temp_max += nums[i] + + if (max_result < temp_max) { + max_result = temp_max; + } + + if (temp_max < 0) { + temp_max = 0; + } + } + + return max_result; } module.exports = { diff --git a/lib/newman_conway.js b/lib/newman_conway.js index 42685b0..8633f8e 100644 --- a/lib/newman_conway.js +++ b/lib/newman_conway.js @@ -1,11 +1,39 @@ +// Newman-Conway sequence: P(n) = P( P(n - 1)) + P(n - P(n - 1)), with intial conditions P(1)=1 and P(2)=1 +// Time Complexity: O(n) - there is a for loop in newmanConway that will run n number of times. The function p that it calls on has a time complexity of O(1) because it directly looks up the values in the array it's adding to. +// Space Complexity: O(n) - both the newmanConway and p functions add n elements to their data structures. -// Time Complexity: -// Space Complexity: +newmanConway = (num) => { + let result = "1 1 " -function newmanConway(num) { - throw new Error("Function not implemented yet...") + if (num < 1) { + throw Error("Number must be greater than or equal to 1"); + } else if (num === 1) { + return result[0]; + + } else if (num === 2) { + return result.trim(); + } + + for (let n = 3; n <= num; n++) { + result += `${p(n)} `; + } + return result.trim(); +} + +const pValues = [0, 1, 1] + +p = (n) => { + if (pValues[n]) { + return pValues[n]; + } + + const pOfN = p(p(n - 1)) + p(n - p(n - 1)); + pValues.push(pOfN); + return pOfN; } + + module.exports = { newmanConway }; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 3a3c5e0..2f1e344 100644 --- a/package-lock.json +++ b/package-lock.json @@ -436,9 +436,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "log-symbols": { @@ -766,9 +766,9 @@ "dev": true }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, "yargs": {