LeetCode第[53]题(Java):Maximum Subarray

题目:和最大的子序列

难度:Medium

题目内容

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

翻译

给定一个整数数组nums,找到相邻的子数组(至少包含一个数字),它的总和是最大的,并返回它的和。

Example:

Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.

Follow up:

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

我的思路:呃,没啥好思路,只会硬刚两个for,遍历所有子序列。。

我的代码:

 1     public int maxSubArray(int[] nums) {
 2         int max = nums[0];
 3         for (int i = 0; i < nums.length; i++) {
 4             int sum = 0;
 5             for (int j = i; j < nums.length; j++) {
 6                 sum += nums[j];
 7                 max = sum > max ? sum : max;
 8             }
 9         }
10         return max;
11     }

我的复杂度:O(n2

编码过程中的问题:(简单地代码有时候问题也是挺多的,可见并不能偷懒,想到方法了即使很简单也要动手写才行)

1、一开始取max 的初值为 0,然后发现当只有一个负数的时候会返回0,所以遍历取最值的时候,max或者min的初值应该取数组内部的值;

2、一开始sum的初值取的是 nums[i], j 从 i + 1 开始,然后发现最后一个元素(也是一个子序列)不会进入判断,所以遍历所有子序列的时候 j 应该是从 i 开始,sum的初值取0;

答案代码

 1     public int maxSubArray(int[] nums) {
 2         int n = nums.length;
 3         int[] dp = new int[n];
 4         dp[0] = nums[0];
 5         int max = dp[0];
 6
 7         for(int i = 1; i < n; i++){
 8             dp[i] = Math.max(dp[i-1] + nums[i], nums[i]);
 9             max = Math.max(max, dp[i]);
10         }
11
12         return max;
13     }

答案复杂度:O(N)

答案思路:采用动态规划的思想,新建一个数组,用它来记录以 nums[i] 结尾的序列能达到的最大值。

取 nums[i] 与 nums[i] + dp[i-1]的最大值就行(dp[i-1]如果大于零,则直接加,否则取nums[i]即为最大)

【注意并不是说dp[i]就表示以nums[i]结尾的序列内子序列能达到的最大值】

所以 dp[] 里面最大的那一个值就是要求的最大的。

优化:

因为只要知道dp的最大值即可,所以不需要把dp新建出来,只要用一个变量mem记录当前的,然后看是否比max大即可:

1     public int maxSubArray(int[] nums) {
2         int max = nums[0];
3         int mem = max;
4         for (int i = 1; i < nums.length; i++) {
5             mem = Math.max(mem + nums[i], nums[i]);
6             max = Math.max(mem, max);
7         }
8         return max;
9     }

扩展:如果我还想知道那个最大子序列的终始位置呢?

 1     public int[] maxSubArray(int[] nums) {
 2         int n = nums.length;
 3         int[][] dp = new int[n][2];
 4         dp[0][0] = nums[0];
 5         int[] max = {dp[0][0], 0, 0};
 6
 7         for(int i = 1; i < n; i++){
 8             if (dp[i - 1][0] < 0) {
 9                 dp[i][0] = nums[i];
10                 dp[i][1] = i;
11             } else {
12                 dp[i][0] = nums[i] + dp[i-1][0];
13                 dp[i][1] = dp[i-1][1];
14             }
15
16             if (max[0] < dp[i][0]) {
17                 max[0] = dp[i][0];
18                 max[1] = dp[i][1];
19                 max[2] = i;
20             }
21         }
22
23         return max;
24     }

算法复杂度:O(N)

max[] 三个元素分别是 max值、起始位置、终止位置

dp的下标就是终止位置了,所以再给dp加一个维度记录此终止位置对应的起始位置  dp[][]

【注意dp[i][1]的值也要根据 dp[i - 1][0] < 0 的判断而变化】

原文地址:https://www.cnblogs.com/Xieyang-blog/p/9030663.html

时间: 2024-07-30 09:17:43

LeetCode第[53]题(Java):Maximum Subarray的相关文章

【LeetCode每天一题】Maximum Subarray(最大子数组)

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum. Example:        Input: [-2,1,-3,4,-1,2,1,-5,4],            Output: 6                 Explanation: [4,-1,2,1] has

lintcode 中等题:maximum subarray difference 最大子数组差

题目 最大子数组差 给定一个整数数组,找出两个不重叠的子数组A和B,使两个子数组和的差的绝对值|SUM(A) - SUM(B)|最大. 返回这个最大的差值. 样例 给出数组[1, 2, -3, 1],返回 6 注意 子数组最少包含一个数 挑战 时间复杂度为O(n),空间复杂度为O(n) 解题 刚做了数组中两个子数组和的最大值,这一题是求差,感觉上题的求解思想应该是可以用的 A B 分别是两个子数组的和,则: 所以 当A>B 的时候A越大越好 B越小越好 当A<B 的时候B越大越好 A越小越好

lintcode 中等题:maximum subarray最大子数组II

题目 最大子数组 II 给定一个整数数组,找出两个不重叠子数组使得它们的和最大. 每个子数组的数字在数组中的位置应该是连续的. 返回最大的和. 您在真实的面试中是否遇到过这个题? Yes 样例 给出数组[1, 3, -1, 2, -1, 2],这两个子数组分别为[1, 3]和[2, -1, 2]或者[1, 3, -1, 2]和[2],它们的最大和都是7 注意 子数组最少包含一个数 挑战 要求时间复杂度为O(n) 解题 最大子数组I 这个题目是求一个数组中一个最大子数组的和,而本题目是求数组中的前

LeetCode第[5]题(Java):Longest Palindromic Substring 标签:String、动态规划

题目中文:求最长回文子串 题目难度:Medium 题目内容: Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. 翻译: 给定一个字符串s,找出s中最长的回文子串.你可以假设s的最大长度是1000. 什么叫回文子串? 就是字符串中,满足能正读反读都一样的子串,就是回文子串.如下所示 Input: "babad"

LeetCode 第53题,最大子序和

题目概述 题目:力扣:53.最大子序和 难易:简单 内容: 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4] 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6. 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/maximum-subarray 第一次思路 首先将数组类型分为三类:1.空数组 2.只有一个

【LeetCode从零单刷】Maximum Subarray

题目: Find the contiguous subarray within an array (containing at least one number) which has the largest sum. For example, given the array [?2,1,?3,4,?1,2,1,?5,4], the contiguous subarray [4,?1,2,1] has the largest sum = 6. 解答: 简单的动态规划.判断以前所有的努力是否对 当前

LeetCode第[26]题(Java):Remove Duplicates from Sorted Array 标签:Array

题目难度:Easy 题目: Given a sorted array, remove the duplicates in-place such that each element appear only once and return the new length. Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extr

LeetCode第[7]题(Java):Reverse Integer 标签:数学

题目:Reverse Integer 难度:Easy 题目内容: Given a 32-bit signed integer, reverse digits of an integer. Note:Assume we are dealing with an environment which could only hold integers within the 32-bit signed integer range. For the purpose of this problem, assum

LeetCode第[42]题(Java):Trapping Rain Water

题目:接雨水 难度:hard 题目内容: Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In