|
| 1 | +packagecom.fishercoder.solutions; |
| 2 | + |
| 3 | +publicclass_918 { |
| 4 | +publicstaticclassSolution1 { |
| 5 | +/** |
| 6 | + * This is my original solution, but results in TLE on LeetCode. |
| 7 | + * Time: O(n^2) |
| 8 | + */ |
| 9 | +publicintmaxSubarraySumCircular(int[]nums) { |
| 10 | +int[]prefixSums; |
| 11 | +intmaxSum =Integer.MIN_VALUE; |
| 12 | +for (inti =0;i <nums.length;i++) { |
| 13 | +prefixSums =newint[nums.length]; |
| 14 | +for (intj =i,k =0;j < (i +nums.length);j++) { |
| 15 | +if (k ==0) { |
| 16 | +prefixSums[k] =nums[(j +nums.length) %nums.length]; |
| 17 | + }else { |
| 18 | +prefixSums[k] =prefixSums[k -1] +nums[(j +nums.length) %nums.length]; |
| 19 | + } |
| 20 | +maxSum =Math.max(maxSum,prefixSums[k++]); |
| 21 | + } |
| 22 | + } |
| 23 | +returnmaxSum; |
| 24 | + } |
| 25 | + } |
| 26 | + |
| 27 | +publicstaticclassSolution2 { |
| 28 | +/** |
| 29 | + * Credit: https://leetcode.com/problems/maximum-sum-circular-subarray/discuss/178422/One-Pass |
| 30 | + * Think of two cases: |
| 31 | + * 1. the max comes from the contiguous part of the original array |
| 32 | + * 2. the max comes from connecting the tail part and the head part of the original array. |
| 33 | + * See graph from the above link. |
| 34 | + * <p> |
| 35 | + * Time: O(n) |
| 36 | + * <p> |
| 37 | + * This is a follow-up from https://leetcode.com/problems/maximum-subarray/ which is solved by Kadane's algorithm. |
| 38 | + */ |
| 39 | +publicintmaxSubarraySumCircular(int[]nums) { |
| 40 | +intcurrMax =0; |
| 41 | +intglobalMax =nums[0]; |
| 42 | +intcurrMin =0; |
| 43 | +intglobalMin =nums[0]; |
| 44 | +inttotal =0; |
| 45 | +for (inti =0;i <nums.length;i++) { |
| 46 | +currMax =Math.max(nums[i],currMax +nums[i]); |
| 47 | +globalMax =Math.max(globalMax,currMax); |
| 48 | +currMin =Math.min(currMin +nums[i],nums[i]); |
| 49 | +globalMin =Math.min(currMin,globalMin); |
| 50 | +total +=nums[i]; |
| 51 | + } |
| 52 | +returnglobalMax >0 ?Math.max(globalMax,total -globalMin) :globalMax; |
| 53 | + } |
| 54 | + } |
| 55 | + |
| 56 | +publicstaticclassSolution3 { |
| 57 | +/** |
| 58 | + * Credit: https://leetcode.com/problems/maximum-sum-circular-subarray/discuss/633058/Java-or-C%2B%2B-or-Python3-or-With-detailed-explanation-or-O(N)-time-or-O(1) |
| 59 | + * This one is similar to the above Solution2, but only slightly differs in that it starts from i = 1 instead of i = 0 |
| 60 | + * And it listed out a few examples to help illustrate why this algorithm makes sense. |
| 61 | + * Which I think is easier to make sense of. |
| 62 | + * <p> |
| 63 | + * Time: O(n) |
| 64 | + * <p> |
| 65 | + * This is a follow-up from https://leetcode.com/problems/maximum-subarray/ which is solved by Kadane's algorithm. |
| 66 | + */ |
| 67 | +publicintmaxSubarraySumCircular(int[]nums) { |
| 68 | +intcurrMax =nums[0]; |
| 69 | +intglobalMax =nums[0]; |
| 70 | +intcurrMin =nums[0]; |
| 71 | +intglobalMin =nums[0]; |
| 72 | +inttotal =nums[0]; |
| 73 | +for (inti =1;i <nums.length;i++) { |
| 74 | +currMax =Math.max(nums[i],currMax +nums[i]); |
| 75 | +globalMax =Math.max(globalMax,currMax); |
| 76 | +currMin =Math.min(currMin +nums[i],nums[i]); |
| 77 | +globalMin =Math.min(currMin,globalMin); |
| 78 | +total +=nums[i]; |
| 79 | + } |
| 80 | +returnglobalMax >0 ?Math.max(globalMax,total -globalMin) :globalMax; |
| 81 | + } |
| 82 | + } |
| 83 | +} |