O(n) runtime O(1) space algorithm explained
The basic idea of the algorithm is to iterate on possible end_of_first_range [1:n-2].\nAnd during the iteration to maintain the following paramters:\n smallest_
The basic idea of the algorithm is to iterate on possible end_of_first_range [1:n-2].\nAnd during the iteration to maintain the following paramters:\n* smallest_indx_for_end_of_second_range which stands for the minimal indx for which the second range ends and holds that the second range sum is geq of the currrent first range sum\n* biggest_indx_for_end_of_second_range  which stands for the maximal indx for which the second range ends and holds that the second range sum is leq of the yielded third range sum\n\nobviously  every possible indx for end of second range in  [smallest_indx_for_end_of_second_range, biggest_indx_for_end_of_second_range] is possible for the current end_of_first_range so we simply mainatin res += the length of [smallest_indx_for_end_of_second_range,  biggest_indx_for_end_of_second_range] (0 if smallest_indx_for_end_of_second_range > biggest_indx_for_end_of_second_range)\n\nSo now we need an algorithm to maintain smallest_indx_for_end_of_second_range, biggest_indx_for_end_of_second_range.\nFor this we simply observe that they are allways advancing right (towards the end of the array). why?\n\n* smallest_indx_for_end_of_second_range  advances only towards right bcs the first does not get smaller\n* biggest_indx_for_end_of_second_range advances only towards right bcs the previous maximal second range does not gets bigger when his first element is advanced forward \n\n* we can maintain those indexes and the relevant partial sums in a constant amount of variables (hence O(1) memory)\n* we only iterate all our indexes(constant amount) forward, hence O(n) time complexity. \n\nThe code below implements the above algorithm (not in a very elegant way, I must admit :-))\n\n\n```\nclass Solution(object):\n    def waysToSplit(self, nums):\n        """\n        :type nums: List[int]\n        :rtype: int\n        """\n        res = 0\n        totalSum = sum(nums)        \n        firstRangeSum = nums[0]\n        \n        smallestIndxForEndOfSecond = 1\n        smallestSecondRangeSum = nums[1]\n        while True:\n            if smallestSecondRangeSum >= firstRangeSum:\n                break\n            smallestIndxForEndOfSecond += 1\n            if smallestIndxForEndOfSecond == len(nums) - 1:\n                return 0\n            smallestSecondRangeSum += nums[smallestIndxForEndOfSecond]\n        \n        biggestIndxForEndOfSecond = len(nums) - 2\n        biggestSecondRangeSum = totalSum - nums[0] - nums[-1]\n        while True:\n            if totalSum - firstRangeSum - biggestSecondRangeSum >= biggestSecondRangeSum:\n                break\n            biggestSecondRangeSum -= nums[biggestIndxForEndOfSecond]                \n            biggestIndxForEndOfSecond -= 1\n            if biggestIndxForEndOfSecond == 0:\n                return 0\n        \n        \n        res += ((biggestIndxForEndOfSecond - smallestIndxForEndOfSecond) + 1)\n        \n        for firstRangeEnd in xrange(1, len(nums) - 2):\n            firstRangeSum += nums[firstRangeEnd]\n            smallestSecondRangeSum -= nums[firstRangeEnd]\n            while True:\n                if smallestSecondRangeSum >= firstRangeSum:\n                    if smallestIndxForEndOfSecond == firstRangeEnd:\n                        smallestIndxForEndOfSecond += 1\n                    break\n                smallestIndxForEndOfSecond += 1                    \n                if smallestIndxForEndOfSecond == len(nums) - 1:\n                    return res % (10 ** 9 + 7)\n                smallestSecondRangeSum += nums[smallestIndxForEndOfSecond] \n            \n\n            biggestSecondRangeSum -= nums[firstRangeEnd]\n            while (biggestIndxForEndOfSecond < len(nums) - 2) and (biggestSecondRangeSum + nums[biggestIndxForEndOfSecond + 1]) <= totalSum - firstRangeSum - (biggestSecondRangeSum + nums[biggestIndxForEndOfSecond + 1]):\n                biggestIndxForEndOfSecond += 1\n                biggestSecondRangeSum += nums[biggestIndxForEndOfSecond]\n            if biggestIndxForEndOfSecond == firstRangeEnd:\n                return res % (10 ** 9 + 7)\n            \n            if biggestIndxForEndOfSecond >= smallestIndxForEndOfSecond:\n                res += ((biggestIndxForEndOfSecond - smallestIndxForEndOfSecond) + 1)\n        \n        return res % (10 ** 9 + 7)\n            \n\n                    \n            \n        \n            \n\n            \n        \n        \n        \n        \n        \n\n            \n        \n                    \n        \n        \n        \n        \n        \n```
['Python']