输入一个整形数组(可能有正数和负数),求数组中连续子数组(最少有一个元素)的最大和。要求时间复杂度为O(n)。
def largestSubSum(nums): for i in range(1,len(nums)): if nums[i-1] > 0: nums[i] = nums[i-1]+nums[i] return max(nums)
int maxSubArraySum(int[] a)
{
int biggestSum = 0, frameSetSum = 0;
for (int i = 0; i <= a.length - 1; i++)
{
frameSetSum = frameSetSum + a[i]; //框集扩增
if(biggestSum < frameSetSum);
{
biggestSum = frameSetSum; //记录最大框集
}
if (frameSetSum < 0)
{
frameSetSum = 0; //发现框集已不能使连续子数组和增大,框集前移
}
return biggestSum;
} 算法2:int maxSubArraySum(int[] a)
{
int frameSetSum = a[0];
int biggestSum = a[0];
for (int i = 1; i < a.length; i++)
{
frameSetSum = Math.max(a[i], frameSetSum + a[i]); //第一个变量大则框集前移,第二个变量大则框集扩增
biggestSum = Math.max(biggestSum, frameSetSum); //记录遍历过程中最大的子数组和
}
return biggestSum;
} 可以看到,算法2中的两句max完全可以由算法1中的两个if替代。思路是完全一样的。 import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int[] dp = new int[n];
dp[0] = input.nextInt();
int res = dp[0];
for (int i = 1; i < n; i++) {
int num = input.nextInt();
dp[i] = dp[i - 1] > 0 ? dp[i - 1] + num : num;
res = Math.max(res, dp[i]);
}
System.out.println(res);
}
}
const readline = require('readline')
const rl = readline.createInterface({
input: process.stdin,
ouput: process.stdout
})
let inArr = []
let n
rl.on('line',line=>{
if(!line) return
inArr.push(line.trim())
n = +inArr[0]
if(inArr.length === n+1){
let arr = []
for (let i = 0; i < n; i++) {
arr[i] = +inArr[i+1]
}
console.log(maxsum(arr))
}
})
function maxsum(arr) {
if(arr.length === 1){
return arr[0]
}
let max = 0, temp = 0
for (let i = 0; i < arr.length; i++) {
temp += arr[i]
max = Math.max(temp,max)
if(temp<0){
temp = 0
}
}
return max
} 比较容易想到的应该是动态规划吧,而且挺容易理解的。设dp[i]表示这个连续子数组以索引i结束时最大和。最后遍历填充完dp后,真实的最大连续子数组和肯定以某个索引结束的,所以找到dp中最大值即可。填充dp时,如果dp[i-1] < 0,那么dp[i]直接等于第i个数nums[i],否则就是dp[i] = dp[i-1] + nums[i]。这个应该很容易理解。
int main () {
int n = 0, temp = 0;
cin >> n;
vector<int> nums, dp(n, 0);
while (cin >> temp) nums.push_back(temp);
dp[0] = nums[0];
for (int i = 1; i < n; i++) {
if (dp[i-1] < 0) dp[i] = nums[i];
else dp[i] = dp[i-1] + nums[i];
}
cout << *max_element(dp.begin(), dp.end()) << endl;
return 0;
}
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
int N;
vector<int> arr;
while(cin>>N){
int tmp;
//保存数组
for(int i=0;i<N;i++){
cin>>tmp;
arr.push_back(tmp);
}
int dp[N];//动态规划
for(int i=0;i<N;i++){
if(i==0)dp[i]=arr[i];
else dp[i]=max(arr[i],dp[i-1]+arr[i]);//状态方程
}
int max_rst=dp[0];//找最大和的值
for(int i=0;i<N;i++){
if(dp[i]>max_rst)max_rst=dp[i];
}
cout<<max_rst<<endl;
}
} 简单的动态规划#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
vector<int>num(n),dp(n,0);
for(int i=0;i<n;i++)
cin>>num[i];
dp[0]=num[0];
int res=dp[0];
for(int i=1;i<n;i++)
{
if(dp[i-1]+num[i]<0)
dp[i]=0;
else
{
dp[i]=dp[i-1]+num[i];
res=max(res,dp[i]);
}
}
cout<<res<<endl;
return 0;
} | importjava.util.*; publicclassMain{ publicstaticvoidmain(String args[]){ Scanner cin = newScanner(System.in); //输入数组长度 intn = cin.nextInt(); int[] arr = newint[n]; //输入n行数据 for(inti=0;i<n;i++){ arr[i] = cin.nextInt(); } System.out.println(maxValue(arr,n)); } //求最大和 publicstaticintmaxValue(int[] arr,intn){ //创建数组dp,大小为arr数组大小 int[] dp = newint[n]; //dp[i]表示从arr[0]到arr[i]的最大和 dp[0] = arr[0]; intmaxValue = dp[0]; for(inti=1;i<n;i++){ //dp[i]的值可能为dp[i-1]+arr[i],也可能为arr[i],取最大值 dp[i] = Math.max(dp[i-1]+arr[i], arr[i]); if(dp[i]> maxValue){ maxValue = dp[i]; } } returnmaxValue; } } |
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int[] nums = new int[N];
for (int i = 0; i < N; i++) {
nums[i] = sc.nextInt();
}
int[] sums = new int[N];
sums[0] = nums[0];
int max = sums[0];
for (int i = 1; i < N; i++) {
sums[i] = Math.max(nums[i], sums[i - 1] + nums[i]);
max = Math.max(max, sums[i]);
}
System.out.println(max);
}
}
#include <bits/stdc++.h>
using namespace std;
int main()
{
int N;
cin >> N;
int sum = -1, temp = 0;
for(int i = 0; i < N; i++)
{
int _;
cin >> _;
temp += _;
if(temp < 0)
{
temp = 0;
}
else
{
sum = max(sum,temp);
}
}
cout << sum << endl;
return 0;
}
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
int[] arr = new int[N];
for(int i=0;i<N;i++){
arr[i] = scanner.nextInt();
}
int[] sums = new int[N];
sums[0]=arr[0];
int max = 0;
int min = 0;
for(int i=1;i<N;i++){
sums[i] = sums[i-1]+arr[i];
max = sums[max]>sums[i]?max:i;
min = sums[min]<sums[i]?min:i;
}
if(max>min){
int ret = sums[max]>sums[max]-sums[min]?sums[max]:sums[max]-sums[min];
System.out.println(ret);
}else{
System.out.println(sums[max]);
}
}
}
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int curmax = 0, imax = -999;
int tmp;
for (int i = 0; i < n; i++) {
cin >> tmp;
curmax += tmp;
imax = max(imax, curmax);
curmax = max(curmax, 0);
}
cout << imax << endl;
return 0;
}