此题是一道求最大子数列的题,算是新手的第一道坎
此题用到了一个比较基础的算法:
public class MaximumSubsequence {
public int maximumSubsequence(int[] a){
int n = a.length;
int thisSum = 0;
int maxSum = 0;
for(int i = 0; i < n; i++){
thisSum += a[i];
if(thisSum > maxSum){
maxSum = thisSum;
} else if(thisSum < 0) {
thisSum = 0;
}
}
return maxSum;
}
}
这个算法的正确性毋庸置疑,只是需要一些时间理解与分析
具体的分析我会写在以后的算法分析专栏里
还有一种算法也能解决此类问题:分治法
分治法的强大型也是毋庸置疑的,许多问题都能用分治法来解决,而且分治法的时间复杂度为 O(n*logn)
是一个非常强大的算法
《=================================================================》
我使用的是第一种算法,因为他的核心代码量较小且时间复杂度仅为线性级-O(n)
但是这个算法目前并不能解决这道题
因为题目要求我们输出的最大子数列的 左坐标、右坐标、累加值
而这个算法目前只能得到累加值
所以需要一些操作来存储左右的坐标
其中需要注意的是:
1.输出格式(如果因为输出格式而错的话就太冤了)
2.如果有多个最大子数列,应取第一个为输出
3.在本题中 最大字数列 不包括 空数列 所以如果有一个 全负数组 那么最大应为最大的那个负数(所以代码中有许多改动的地方)
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
for (int i = 1; i <= t; i++) {
int[] x = new int[100005];
int n = sc.nextInt();
for (int j = 1; j <= n; j++) {
x[j] = sc.nextInt();
}
int thisSum = 0;
int maxSum = -999999;
int maxLeft = 0;
int maxRight = 0;
int left = 0;
int right = 0;
for (int j = 1; j <= n; j++) {
if (j == 1) {
left = right = 1;
} else {
right++;
}
thisSum += x[j];
if (thisSum > maxSum) {
maxSum = thisSum;
maxLeft = left;
maxRight = right;
}
if (thisSum < 0) {
thisSum = 0;
left = j + 1;
}
}
System.out.println("Case " + i + ":");
System.out.println(maxSum + " " + maxLeft + " " + maxRight);
if (i != t) {
System.out.println();
}
}
}
}
如果你感觉都差不多了,却仍然WA,可以取本题的讨论区,里面有很多大佬给出的样例
总有一组样例能解决你的问题