Topics and use cases
package pid053; /*Maximum suborder sum Given an integer array nums, find a continuous subarray with the largest sum (subarray contains at least one element), and return its maximum sum. Example: Input: [- 2,1, - 3,4, - 1,2,1, - 5,4], Output: 6 Explanation: the sum of continuous subarrays [4, - 1,2,1] is the largest, which is 6. Advanced: If you have implemented the solution with O(n) complexity, try to use a more refined divide and conquer method. */ public class main { public static void main(String[] args) { int[][] testTable = {{-2,1,-3,4,-1,2,1,-5,4},{-1,-2,-3,-4,-1},{7,-6,4,3,1},{-1,6,2,7}}; for (int[] ito : testTable) { test(ito); } } private static void test(int[] ito) { Solution solution = new Solution(); int rtn; long begin = System.currentTimeMillis(); for (int i = 0; i < ito.length; i++) { System.out.print(ito[i]+" "); } System.out.println(); //Print array at start rtn = solution.maxSubArray(ito);//Execution procedure long end = System.currentTimeMillis(); //System.out.println(ito + ": rtn=" + rtn); System.out.println( " rtn=" +rtn); // for (int i = 0; i < ito.length; i++) { // System.out.print(ito[i]+" "); // }//Several arrays of printing results System.out.println(); System.out.println("Time consuming:" + (end - begin) + "ms"); System.out.println("-------------------"); } }
Solution 1 (successful, 16ms, fast)
Speed o(n)
If the current value is added to a negative number, update the max value first
Then add a negative number. If it is less than 0, it will be initialized to 0. Otherwise, it will be ignored
If the final max is 0, it is proved that all of them are negative numbers, then take the largest of the negative numbers
package pid053; class Solution { public int maxSubArray(int[] nums) { int length=nums.length; if(length==0){ return 0; } int totalMax=0; int nowMax=0; for(int i=0;i<length;i++){ int now=nums[i]; if(nowMax==0){//A New Beginning if(now>=0){ nowMax=now; continue; } else { continue; } } else {//There was a peace before if(now>=0){ nowMax=nowMax+now; continue; } else{//Last and temporary end enter subtraction mode if(nowMax>totalMax){//Plus the negative positive decreases, update the max value first totalMax=nowMax; } nowMax=nowMax+now; if(nowMax<0){ nowMax=0; } continue; } } } if(nowMax>totalMax){ totalMax=nowMax; } if(totalMax==0){//All negative totalMax=nums[0]; for(int i=0;i<length;i++){ int now=nums[i]; if(now>totalMax){ totalMax=now; } } } return totalMax; } }
Solution 2 (others)
dp algorithm, the idea is the same as mine, but very simple
class Solution { public: int maxSubArray(vector<int>& nums) { int size=nums.size(); int sum=0; int max=INT_MIN; for(int i=0; i<size; i++){ sum+=nums[i]; if(sum>max){ max=sum; } if(sum<0){ sum=0; } } return max; } };
Solution 3 (others)
dynamic programming
More concise
The program is
sum=max(sum,nums[i]); max_sum=max(sum,max_sum);
int maxSubArray(vector<int>& nums) { if(nums.empty()) return 0; int sum=nums[0]; int max=sum; for(int i=1;i<nums.size();++i){ sum=(sum+nums[i])>nums[i]?(sum+nums[i]):nums[i]; max=sum>max?sum:max; } return max; } ---------------------
Solution 4 (others)
Divide and Conquer: Idea: suppose the valid range of array subscript is from L to r, divide the array into left half subscript (L, mid-1) and right half subscript (mid+1, r) and middle element subscript (MID). Next, recursively find the maximum sub order sum of left half: left=helper(nums,l,mid-1); right=helper(nums,mid+1,r); next, left half and right Boundary, the left boundary of the right half and the middle element nums[mid] are integrated. Two cycles are used. First, the right boundary and the middle value of the left half are integrated, and then the integration result and the left boundary of the right half are integrated to get the maximum suborder and max_num after integration. Finally, the maximum value of max_num, left,right is the maximum suborder sum required.
class Solution { public: int maxSubArray(vector<int>& nums) { if(nums.size()==0)return 0; return helper(nums,0,nums.size()-1); } int helper(vector<int>& nums,int l,int r){ if(l>r)return INT_MIN;//Note that this is not a return of 0, such as {- 2, - 1}. After the partition and treatment, it becomes three parts: left middle right n {- 1, {- 2}. The left half should return int min, //Because it is also compared with the return value of the right half, the final correct result returns - 1. If the left half returns 0, 0 > - 2, and is greater than the maximum combination value (- 1) of the left middle right, the final result returns 0, and an error occurs if(l==r)return nums[l]; int mid=(l+r)/2; int left=helper(nums,l,mid-1); int right=helper(nums,mid+1,r); int t=nums[mid]; int max_num=nums[mid]; for(int i=mid-1;i>=l;i--){ t+=nums[i]; max_num=max(max_num,t); } t=max_num; for(int i=mid+1;i<=r;i++){ t+=nums[i]; max_num=max(max_num,t); } return max(max(left,right),max_num); } };