多方法 01

141 阅读2分钟

53.最大子序和

原题链接

滑动窗口 / 暴力

/*
 * 1、滑动窗口算法,或称为暴力法
 * 左指针遍历数组,右指针从左指针位置开始,向队尾遍历
 * 从中找到最大子序列和
 * 
 * 时间复杂度O(n) = n ^ 2;
 * 空间复杂度O(m) = 1;
 * Code by Java; 
 * 
 */
public /* static */ int maxSubArray(int[] nums) {
	int n = nums.length;
	if(n == 0) return 0;
	if(n == 1) return nums[0];
	int max = 0;
	for (int i = 0; i < n; i++) {
		int sum = 0;
		for (int j = i; j < n; j++) {
			sum += nums[j];
			max = Math.max(max, sum);
		}
	}
	return max;
}  

动态规划

/*
 * 2、动态规划算法
 * 
 * 时间复杂度O(n) = n
 * 空间复杂度O(m) = 1	因为是用一个变量ans来存储最终的结果值,没用数组
 * 
 * Code by java
 */
public int maxSubArray(int[] nums) {
	int ans = nums[0];
	int sum = 0;
	for (int num : nums) {
		if (sum > 0) {
			sum += num;		//前面子序列累加的和为正数,则加上现在遍历的这个数
		} else {
			sum = num;		//前面子序列累加的和为负数,则不管是加上还是减去现在遍历的数,大小也比不过直接替换当前的数大(无论正负)
		}					//因为sum为负,累加到一个数上一定是减小的,要取最大,就直接替代
		ans = Math.max(ans, sum);		//最后再将结果与上面累加过新遍历数进行比较,更新结果值
	}
	return ans;
}

动态规划(2)

/*
 * 2、动态规划算法(2)
 * 
 * 时间复杂度O(n) = n
 * 空间复杂度O(m) = n	
 * 
 * Code by java
 */
public int maxSubArray(int[] nums) {
	int[] dp = new int[nums.length];			//dp数组的值,用来存储从该位置到队尾组成的若干子序列总和的最大数
	dp[0] = nums[0];
	int max = nums[0];
	for (int i = 1; i < nums.length; i++) {
		dp[i] = Math.max(dp[i-1] + nums[i], nums[i]);		
		if (max < dp[i]) {
			max = dp[i];
		}
	}
	return max;
}

贪心算法

/*
 * 3、贪心算法
 * 从头遍历到尾,依次累加,如果累加器(sum)为负
 * 若累加,则结果值就会减小,所以在下次遍历前,把累加器sum归零
 * 相当于重新开始
 */
public int maxSubArray(int[] nums) {
	int ans = Integer.MIN_VALUE;
	int n = nums.length;
	int sum = 0;
	for (int i = 0; i < n; i++) {
		sum += nums[i];
		ans = Math.max(ans, sum);	//更新结果值
		if(sum < 0) {
			sum = 0;		//if sum < 0 重新开始找子序列
		}
	}
	return ans;
}