leetcode-53- 最大子序和(maximum subarray)-java
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了leetcode-53- 最大子序和(maximum subarray)-java,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3730字,纯文字阅读大概需要6分钟。
内容图文
题目及用例
package pid053;
/*最大子序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
*/
public class main {
public static void main(String[] args) {
int[][] testTable = {{-2,1,-3,4,-1,2,1,-5,4},{-1,-2,-3,-4,-1},{7,-6,4,3,1},{-1,6,2,7}};
for (int[] ito : testTable) {
test(ito);
}
}
private static void test(int[] ito) {
Solution solution = new Solution();
int rtn;
long begin = System.currentTimeMillis();
for (int i = 0; i < ito.length; i++) {
System.out.print(ito[i]+" ");
}
System.out.println();
//开始时打印数组
rtn = solution.maxSubArray(ito);//执行程序
long end = System.currentTimeMillis();
//System.out.println(ito + ": rtn=" + rtn);
System.out.println( " rtn=" +rtn);
// for (int i = 0; i < ito.length; i++) {
// System.out.print(ito[i]+" ");
// }//打印结果几数组
System.out.println();
System.out.println("耗时:" + (end - begin) + "ms");
System.out.println("-------------------");
}
}
解法1(成功,16ms,较快)
速度o(n)
方法就是不断累加,如果现在的值加到负数,先更新max值
然后加上负数,如果小于0,则初始化为0,否则就不管
如果最后max为0,证明全是负数,则取负数中的最大的那个数
package pid053;
class Solution {
public int maxSubArray(int[] nums) {
int length=nums.length;
if(length==0){
return 0;
}
int totalMax=0;
int nowMax=0;
for(int i=0;i<length;i++){
int now=nums[i];
if(nowMax==0){//新的开始
if(now>=0){
nowMax=now;
continue;
}
else {
continue;
}
}
else {//之前已经有和了
if(now>=0){
nowMax=nowMax+now;
continue;
}
else{//上一个的和暂时结束进入减法模式
if(nowMax>totalMax){//加上负的肯定变小,先更新max值
totalMax=nowMax;
}
nowMax=nowMax+now;
if(nowMax<0){
nowMax=0;
}
continue;
}
}
}
if(nowMax>totalMax){
totalMax=nowMax;
}
if(totalMax==0){//全为负的情况
totalMax=nums[0];
for(int i=0;i<length;i++){
int now=nums[i];
if(now>totalMax){
totalMax=now;
}
}
}
return totalMax;
}
}
解法2(别人的)
dp算法,思路和我的一样,但是很简洁
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int size=nums.size();
int sum=0;
int max=INT_MIN;
for(int i=0; i<size; i++){
sum+=nums[i];
if(sum>max){
max=sum;
}
if(sum<0){
sum=0;
}
}
return max;
}
};
解法3(别人的)
动态规划
更加简洁
程式就是
sum=max(sum,nums[i]);
max_sum=max(sum,max_sum);
int maxSubArray(vector<int>& nums) {
if(nums.empty()) return 0;
int sum=nums[0];
int max=sum;
for(int i=1;i<nums.size();++i){
sum=(sum+nums[i])>nums[i]?(sum+nums[i]):nums[i];
max=sum>max?sum:max;
}
return max;
}
---------------------
解法4(别人的)
分治法:思路:假设数组下标有效范围是l到r,将数组分为左半部分下标为(l,mid-1)和右半部分下标为(mid+1,r)以及中间元素下标为mid,接下来递归求出左半部分的最大子序和:left=helper(nums,l,mid-1); 右半部分最大子序和right=helper(nums,mid+1,r);接下来再将左半部分右边界,右半部分左边界以及中间元素nums[mid]整合,用了两个循环,先整合左半部分右边界和中间值,再将整合结果与右半部分左边界整合得到整合以后的最大子序和max_num,最后返回max_num,left,right的最大值即是要求的最大子序和。
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if(nums.size()==0)return 0;
return helper(nums,0,nums.size()-1);
}
int helper(vector<int>& nums,int l,int r){
if(l>r)return INT_MIN;//注意此处不是返回0,比如{-2,-1},分治以后变为左中右n{},-1,{-2}三部分。左半部分{}应返回INT_MIN,
//因为还要和右半部分的返回值进行比较,最终正确结果返回-1。若左半部分返回0,0>-2,且大于左中右的最大组合值(-1),最终结果返回0,出错
if(l==r)return nums[l];
int mid=(l+r)/2;
int left=helper(nums,l,mid-1);
int right=helper(nums,mid+1,r);
int t=nums[mid];
int max_num=nums[mid];
for(int i=mid-1;i>=l;i--){
t+=nums[i];
max_num=max(max_num,t);
}
t=max_num;
for(int i=mid+1;i<=r;i++){
t+=nums[i];
max_num=max(max_num,t);
}
return max(max(left,right),max_num);
}
};
内容总结
以上是互联网集市为您收集整理的leetcode-53- 最大子序和(maximum subarray)-java全部内容,希望文章能够帮你解决leetcode-53- 最大子序和(maximum subarray)-java所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。