C++/Java/Python O(n) with picture
The approach is not too hard, but the implementation was tricky for me to get right.\n\nFirst, we prepare the prefix sum array, so that we can compute subarray 
The approach is not too hard, but the implementation was tricky for me to get right.\n\nFirst, we prepare the prefix sum array, so that we can compute subarray sums in O(1). Then, we move the boundary of the first subarray left to right. This is the first pointer - `i`.\n\nFor each point `i`, we find the minimum (`j`) and maximum (`k`) boundaries of the second subarray:\n- `nums[j] >= 2 * nums[i]`\n- `nums[sz - 1] - nums[k] >= nums[k] - nums[i] `\n\n> Note that in the code and examples below, `k` points to the element *after* the second array. In other words, it marks the start of the (shortest) third subarray. This makes the logic a bit simpler.\n\nWith these conditions, sum(0, i) <= sum(i + 1, j), and sum(i + 1, k - 1) < sum(k, n). Therefore, for a point `i`, we can build `k - j ` subarrays satisfying the problem requirements.\n\nFinal thing is to realize that j and k will only move forward, which result in a linear-time solution. \n\nThe following picture demonstrate this approach for the `[4,2,3,0,3,5,3,12]` test case.\n\n![image](https://assets.leetcode.com/users/images/1f373639-66e5-496e-9450-15fde8836ad9_1609707433.9044826.png)\n**C++**\n```cpp\nint waysToSplit(vector<int>& nums) {\n    int res = 0, sz = nums.size();\n    partial_sum(begin(nums), end(nums), begin(nums));\n    for (int i = 0, j = 0, k = 0; i < sz - 2; ++i) {\n        j = max(i + 1, j);\n        while (j < sz - 1 && nums[j] < nums[i] * 2)\n            ++j;\n        k = max(j, k);\n        while (k < sz - 1 && nums[k] - nums[i] <= nums[sz - 1] - nums[k])\n            ++k;\n        res = (res + k - j) % 1000000007;\n    }\n    return res;\n} \n```\n**Java**\n```java\npublic int waysToSplit(int[] nums) {\n    int sz = nums.length, res = 0;\n    for (int i = 1; i < sz; ++i)\n        nums[i] += nums[i - 1];\n    for (int i = 0, j = 0, k = 0; i < sz - 2; ++i) {\n        while (j <= i || (j < sz - 1 && nums[j] < nums[i] * 2))\n            ++j;\n        while (k < j || ( k < sz - 1 && nums[k] - nums[i] <= nums[sz - 1] - nums[k]))\n            ++k;\n        res = (res + k - j) % 1000000007;\n    }    \n    return res;\n}\n```\n**Python**\n```python\nclass Solution:\n    def waysToSplit(self, nums: List[int]) -> int:\n        sz, res, j, k = len(nums), 0, 0, 0\n        nums = list(accumulate(nums))\n        for i in range(sz - 2):\n            while j <= i or (j < sz - 1 and nums[j] < nums[i] * 2):\n                j += 1\n            while k < j or (k < sz - 1 and nums[k] - nums[i] <= nums[-1] - nums[k]):\n                k += 1\n            res = (res + k - j) % 1000000007\n        return res\n```\n**Complexity Analysis**\n- Time: O(n)\n- Memory: O(n) for the prefix sum array - or O(1) as we reuse the input.
[]