LeetCode力扣(数组53:最大子数组和)

LeetCode力扣(数组53:最大子数组和)

难度:中等

题目:

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组 是数组中的一个连续部分。

示例:

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
示例 2:

输入:nums = [1]
输出:1
示例 3:

输入:nums = [5,4,-1,7,8]
输出:23

提示:

1 <= nums.length <= 105
-104 <= nums[i] <= 104

进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。

思路:

  • 方法一:使用动态规划法(使用另一个数组记录nums[i]连续子数组的最大值)
  • 方法二:贪心算法(使用前缀比较)
  • 方法三:暴力算法使用临时变量设置局部最大值和全局最大值

代码:

public class Array02 {

	public static void main(String[] args) {
		int[] nums = { -2, 1, -3, 4, -1, 2, 1, -5, 4 };
		int i = maxSubArray(nums);
		System.out.println(i);
	}

	// 动态规划法
	public static int maxSubArray(int[] nums) {
		int len = nums.length;
		// dp[i]表示nums[i]连续子数组的最大值
		int[] dp = new int[len];
		dp[0] = nums[0];
		int max = nums[0]; //最大值
		
		for (int i = 1; i < len; i++) {
			// 使用动态规划,dp[i]保存子窜最大值
			if (dp[i-1] < 0) {
				dp[i] = nums[i];
			}else {
				dp[i] = dp[i-1] + nums[i];
			}
			// 最大值
			if(dp[i] > max) {
				max = dp[i];
			}
		}
		return max;
	}

	// 贪心法
	public static int maxSubArray2(int[] nums) {
		int max = nums[0];
		int temp = 0;
		for (int num : nums) {
			temp = Math.max(temp + num, num);
			max = Math.max(temp, max);
		}
		return max;
	}

	// 使用临时变量设置局部最大值和全局最大值
	public static int maxSubArray1(int[] nums) {
		int max = nums[0];
		int temp = nums[0]; // 每轮临时
		for (int i = 1; i < nums.length; i++) {
			if (temp + nums[i] > nums[i]) {
				temp = temp + nums[i];
			} else {
				temp = nums[i];
			}
			if (temp > max) {
				max = temp;
			}
		}
		return max;
	}
}

运行结果:

image-20220913192417616

提交结果 执行用时 内存消耗 语言 提交时间 备注
通过 1 ms 50.7 MB Java 2022/09/13 18:48 动态规划法
通过 1 ms 50 MB Java 2022/09/13 18:36 贪心算法
通过 1 ms 50.3 MB Java 2022/09/13 18:36 贪心算法
通过 1 ms 50.8 MB Java 2022/09/13 15:42 暴力破解(利用数字的正负性,正的加,负的不加)

END

posted @ 2022-09-13 19:26  lyluoye  阅读(44)  评论(0)    收藏  举报