3 pointers in O(n) time complexity
\n# Code\n\nclass Solution {\n    public int waysToSplit(int[] nums) {\n        // O(n) since all the indicators (i, j, k) traverse through the n indices in the
\n# Code\n```\nclass Solution {\n    public int waysToSplit(int[] nums) {\n        // O(n) since all the indicators (i, j, k) traverse through the n indices in the worst case scenario\n        int mod = 1_000_000_007;\n        int n = nums.length;\n        \n        int[] preSum = new int[n];\n        preSum[0] = nums[0];\n        for(int i = 1; i<n; i++) {\n            preSum[i] = preSum[i-1] + nums[i];\n        }\n        int totalSum = preSum[n-1];\n        int ways = 0;\n        int i = 0, j = 0, k = 0;\n        //split range into 3 parts: [0, i], [i+1, j], [j+1, n-1]\n        for (; i < n - 2 && 3 * preSum[i] <= totalSum; i++) {\n            //the pointer j already possesses a more advantageous position than starting from i + 1\n            //To prevent unnecessary iterations, we take advantage of the current position of j by updating it using Math.max(j, i + 1). \n            //This adjustment avoids redundant calculations and contributes to an O(n) time complexity, as opposed to a less optimal O(n^2) scenario that would arise if we started j from i + 1.\n            j = Math.max(j, i + 1);\n            while (j < n - 1 && preSum[j] - preSum[i] < preSum[i]){\n                j++;\n            } \n            // the same logic applied to k pointer \n            k = Math.max(k, j);\n            while (k < n - 1 && preSum[k] - preSum[i] <= totalSum - preSum[k]) {\n                k++;\n            }               \n            ways += (k - j) % mod;\n            ways %= mod;\n        }\n        return ways;\n    }\n}\n```
['Java']