算法题 |
算法刷题专栏 | 面试必备算法 | 面试高频算法
越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨
作者简介:硕风和炜,CSDN-Java领域新星创作者,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验分享|好用的网站工具分享
恭喜你发现一枚宝藏博主,赶快收入囊中吧
人生如棋,我愿为卒,行动虽慢,可谁曾见我后退一步?
算法题 |
给你一个整数数组 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) 的解法,尝试使用更为精妙的 分治法 求解。
枚举小于 cur 的子数组选或不选
,比如当前来到了cur位置,那么cur位置的结果可能来自有哪些情况组成呢?1. 就由当前的位置组成,当前位置就是最大的。 2. 还有可能是前一个位置最大连续子数组的和+当前位置的结果。class Solution {
public int max = Integer.MIN_VALUE;
public int maxSubArray(int[] nums) {
for (int i = 0; i < nums.length; i++) {
max = Math.max(max, process(i,nums));
}
return max;
}
// 当前位置结尾最大值
public int process(int index,int[] nums){
if(index<0) return 0;
return Math.max(process(index-1,nums)+nums[index],nums[index]);
}
}
时间超限了,不要紧哦,我还有锦囊妙计!
class Solution {
public int max = Integer.MIN_VALUE;
public int[] dp;
public int maxSubArray(int[] nums) {
int n=nums.length;
dp=new int[n];
Arrays.fill(dp,-1);
for (int i = 0; i < nums.length; i++) {
max = Math.max(max, process(i,nums));
}
return max;
}
public int process(int index,int[] nums){
if(index<0) return 0;
if(dp[index]!=-1) return dp[index];
return dp[index]=Math.max(process(index-1,nums)+nums[index],nums[index]);
}
}
class Solution {
public int max = Integer.MIN_VALUE;
public int[] dp;
public int maxSubArray(int[] nums) {
int n=nums.length;
dp=new int[n];
dp[0]=nums[0];
max=dp[0];
for (int index=1;index<n;index++) {
dp[index]=Math.max(dp[index-1]+nums[index],nums[index]);
max = Math.max(max, dp[index]);
}
return max;
}
}
空间优化即可。
class Solution {
public int max = Integer.MIN_VALUE;
public int maxSubArray(int[] nums) {
int n=nums.length;
int pre=nums[0];
max=pre;
for (int index=1;index<n;index++) {
pre=Math.max(pre+nums[index],nums[index]);
max = Math.max(max, pre);
}
return max;
}
}
public class Solution {
public int maxSubArray(int[] nums) {
int n = nums.length;
if (n == 0) {
return 0;
}
return process(nums, 0, n - 1);
}
public int process(int[] nums, int left, int right) {
if (left == right) {
return nums[left];
}
int mid = left + (right - left) / 2;
int sum = 0;
int leftSum = Integer.MIN_VALUE;
for (int i = mid; i >= left; i--) {
sum += nums[i];
if (sum > leftSum) {
leftSum = sum;
}
}
sum = 0;
int rightSum = Integer.MIN_VALUE;
for (int i = mid + 1; i <= right; i++) {
sum += nums[i];
if (sum > rightSum) {
rightSum = sum;
}
}
return Math.max(process(nums, left, mid), Math.max(process(nums, mid + 1, right), leftSum+rightSum));
}
}
最后,我想和大家分享一句一直激励我的座右铭,希望可以与大家共勉! |