leetcode-53-maximum subarray-java

Keywords: less Programming

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);
    }
};

Posted by bluejay002 on Wed, 18 Dec 2019 14:25:45 -0800