算法:最大子序列和问题

第一种解法:

  也是最简单的解法,时间复杂度为O(N^2)

复制代码
 1     //O(n^2)
 2     //直接简单粗暴
 3     public void solution1(int[] ints) {
 4         int maxSum = ints[0];
 5         for (int i = 0; i < ints.length; i++) {
 6             int sum = 0;
 7             for (int j = i; j < ints.length; j++) {
 8                 sum += ints[j];
 9                 if (maxSum < sum) {
10                     maxSum = sum;
11                 }
12             }
13         }
14         System.out.println(maxSum);
15     }
复制代码

第二种解法:

  分治法,利用递归的思想,将问题不断分解为最小段。在本例中,最大序列可能出现在左半段、右半段以及中间部分:将序列不断分解。在某一层级中,求出左子段和右字段最大值后,中间部分在分别向两个求出最大值相加,最后比较三个部分的最大值。时间复杂度为O(NlogN)

复制代码
 1     //都为闭区间
 2     //分治法
 3     //O(NlogN)
 4     /*
 5         T(N)=2T(N/2)+N;
 6         T(1)=1;
 7         T(2)=4;
 8         T(4)=32;
 9         T(N)=O(Nlog(N));
10      */
11     public int solution2(int[] ints,int start,int end) {
12         //仅有一个元素,直接返回
13         if (start == end) {
14             return ints[start];
15         }
16         int maxLeft;
17         int maxRight;
18         int splitIndex = (start + end) / 2;
19         //左半边
20         maxLeft = solution2(ints,0,splitIndex);
21         //右半边
22         maxRight = solution2(ints,splitIndex + 1,end);
23         //中间
24         int sumLeft = ints[splitIndex];
25         int sumRight = ints[splitIndex + 1];
26         //向左求包含最后一个的最大和
27         int sum = 0;
28         for (int i = splitIndex; i >= start; i--) {
29             sum += ints[i];
30             sumLeft = Math.max(sum,sumLeft);
31         }
32         //向右求包含第一个的最大和
33         int sum1 = 0;
34         for (int i = splitIndex + 1; i <= end; i++) {
35             sum1 += ints[i];
36             sumRight = Math.max(sum1,sumRight);
37         }
38 
39         return Math.max(sumLeft + sumRight,Math.max(maxLeft,maxRight));
40     }
复制代码

 

第三种解法

  数学分析法。时间复杂度为O(N)

复制代码
 1     //最大前N项和-最小前K项和=最大子序列和
 2     //O(N)
 3     public void solution3(int[] ints) {
 4         int maxSum = ints[0];
 5         int minSum = 0;
 6         int sum = 0;
 7         for (int i = 0; i < ints.length; i++) {
 8             sum += ints[i];
 9             maxSum = Math.max(maxSum,sum-minSum);//-9
10             minSum = Math.min(minSum,sum);//0
11         }
12         System.out.println(maxSum);
13     }
复制代码

 

  测试如下,三个不同的序列

1     public void test01() {
2         //int[] ints = {1, -2, 3, 5, -3, 2};
3         int[] ints = {-9, -2, -3, -5, -3};
4         //int[] ints = {1, 2, 3};
5         solution1(ints);
6         System.out.println(solution2(ints, 0, ints.length-1));
7         solution3(ints);
8     }

 

posted @   厄舍屋下  阅读(50)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示