算法:最大子数组own

转载标明出处:http://i.cnblogs.com/EditPosts.aspx?postid=4726782&update=1

暴力法:

 1 // maxValue.cpp : 定义控制台应用程序的入口点。
 2 //
 3
 4 #include "stdafx.h"
 5 #include <iostream>
 6
 7 using namespace std;
 8
 9 int findMax(int *a,int low,int high,int &sub_left,int &sub_right,int &sub_sum)
10 {
11     if (low==high)
12     {
13         if(a[low]>0)
14         {
15             sub_left=low;
16             sub_right=high;
17             sub_sum=a[low];
18         }
19         else sub_sum=0;
20     }
21
22     else
23     {
24         for(int i=0;i<=high;i++)
25         {
26             int tempSum=0;
27             for (int j=i;j<=high;j++)
28             {
29                 tempSum+=a[j];
30                 if (tempSum>sub_sum)
31                 {
32                     sub_sum=tempSum;
33                     sub_left=i;
34                     sub_right=j;
35                 }
36             }
37         }
38     }
39     return 0;
40 }
41
42 int _tmain(int argc, _TCHAR* argv[])
43 {
44     int sub_left=0;
45     int sub_right=0;
46     int sub_sum=0;
47     int a[]={13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
48     findMax(a,0,15,sub_left,sub_right,sub_sum);
49     cout<<sub_left<<" "<<sub_right<<" "<<sub_sum<<endl;
50     system("pause");
51     return 0;
52 }

时间复杂度:O(n*n);

分治法:

// maxSubArray.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>

using namespace std;

int Find_Max_cross_subArray(int *a,int low,int middle,int high,int &max_left,int &max_right,int &max_value)
{
    int left_sum=-100;
    int sum=0;
    for (int i=middle;i>=low;i--)
    {
        sum+=a[i];
        if (sum>left_sum)
        {
            left_sum=sum;
            max_left=i;
        }
    }

    int right_sum=-100;
    sum=0;
    for (int j=middle+1;j<=high;j++)
    {
        sum+=a[j];
        if (sum>right_sum)
        {
            right_sum=sum;
            max_right=j;
        }
    }
    max_value=left_sum+right_sum;
    return 0;

}

int Find_Max_subArray(int *a,int low,int high,int &max_left,int &max_right,int &max_vlaue)
{
    if (low==high)
    {
        if (a[low]>0)
        {
            max_vlaue=a[low];
            max_left=low;
            max_right=high;
        }
        else max_vlaue=0;
    }
    else
    {
        int middle=(low+high)/2;
        int tem_left_low;
        int tem_left_high;
        int tem_left_sum;
        Find_Max_subArray(a,low,middle,tem_left_low,tem_left_high,tem_left_sum);

        int tem_right_low;
        int tem_right_high;
        int tem_right_sum;
        Find_Max_subArray(a,middle+1,high,tem_right_low,tem_right_high,tem_right_sum);

        int tem_cross_low;
        int tem_cross_high;
        int tem_cross_sum;
        Find_Max_cross_subArray(a,low,middle,high,tem_cross_low,tem_cross_high,tem_cross_sum);

        if (tem_left_sum>=tem_right_sum&&tem_left_sum>=tem_cross_sum)
        {
            max_left=tem_left_low;
            max_right=tem_left_high;
            max_vlaue=tem_left_sum;
        }
        else if (tem_right_sum>=tem_left_sum&&tem_right_sum>=tem_cross_sum)
        {
            max_left=tem_right_low;
            max_right=tem_right_high;
            max_vlaue=tem_right_sum;
        }
        else
        {
            max_left=tem_cross_low;
            max_right=tem_cross_high;
            max_vlaue=tem_cross_sum;
        }
    }
    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
    int max_left=0;
    int max_right=0;
    int max_value=0;
    int a[]={13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
    Find_Max_subArray(a,0,15,max_left,max_right,max_value);
    cout<<max_left<<" "<<max_right<<" "<<max_value<<endl;
    system("pause");
    return 0;
}

递归式: T(n)=2*T(n/2)+Theta(n);n>1

T(n)=theta(1);

非递归线性算法:(4.1-5)

此方是看了我转载的那个伙伴的才有思路,和为负数,就跳过。

 1 // Max_Value.cpp : 定义控制台应用程序的入口点。
 2 //
 3
 4 #include "stdafx.h"
 5 #include <iostream>
 6 using namespace std;
 7
 8 int Max(int *a,int low,int high,int &sub_left,int &sub_right,int &sub_sum)
 9 {
10     if (low==high)
11     {
12         if (a[low]>0)
13         {
14             sub_sum=a[low];
15             sub_left=low;
16             sub_right=high;
17         }
18         else sub_sum=0;
19     }
20     int tempSum=0;
21     for (int i=low;i<=high;i++)
22     {
23         tempSum+=a[i];
24         if (tempSum<=0)
25         {
26             tempSum=0;
27             sub_left=i+1;
28         }
29         if (tempSum>sub_sum)
30         {
31             sub_sum=tempSum;
32             sub_right=i;
33         }
34     }
35     return 0;
36 }
37 int _tmain(int argc, _TCHAR* argv[])
38 {
39     int sub_left=0;
40     int sub_right=0;
41     int sub_sum=0;
42     int a[]={13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
43     Max(a,0,15,sub_left,sub_right,sub_sum);
44     cout<<sub_left<<" "<<sub_right<<" "<<sub_sum<<endl;
45     system("pause");
46     return 0;
47 }

只扫描了一遍,时间复杂度为O(n);

以上方法输出结果都一样:7 10 43

时间: 2024-10-05 08:01:17

算法:最大子数组own的相关文章

分治算法——最大子数组

表示很久没有接触算法了,好多东西真心要一点点拾掇起来,为了找份好工作,我也是蛮拼的了. 好吧,下来说说分治算法,因为在leetcode上刚好碰到这么个问题,想到要用分治做,但是一时又不清楚具体步骤.于是抱起<算法导论>啃起来.刚好上面的例子也是这个算法,就研读了一下. 假定,我们要寻找子数组A[low...high]的最大字数组,使用分治算法,其结果必定是以下三种情况中的一个: 1.完全位于子数组A[low...mid]中,因此low <= i <= j <= mid 2.完

算法导论3:最大子数组问题 2016.1.3

顶着期末复习的压力,还是在今天过完之前看完了一个算法——最大子数组问题. <算法导论>中引入这个问题是通过股票的购买与出售,经过问题转换(转换的过程比较简单,但是不好想),将前一天的当天的股票差价重新表示出来,即转为了一个最大子数组的问题 ,具体内容是:   13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7   找到这连续的16个数里面的连续和最大的子数组;   书中差不多是这个意思:假定我们要寻找子数组A[lo

第四章 分治策略 4.1 最大子数组问题 (暴力求解算法)

/** * 最大子数组的暴力求解算法,复杂度为o(n2) * @param n * @return */ static MaxSubarray findMaxSubarraySlower(int[] n) { long tempSum = 0; int left = 0; int right = 0; long sum = Long.MIN_VALUE; for (int i = 0; i < n.length; i++) { for (int j = i; j < n.length; j++

ubuntu16.04下配置JDK 1.8+安装Java EE,并实现最大子数组算法

软工第二次作业: 1.在个人电脑中安装一个集成开发环境(Microsoft Visual Studio.Eclipse或其它工具均可),要求该环境能够提供单元自动测试功能: 2.记录安装过程,并将全部内容发表在博客中: 3.实现最大子数组和算法,并将该段代码上传至Coding.net系统中: 4.自行选择合适的覆盖标准并设计测试用例对该段代码进行测试,并将测试结果发布在博客中,结果以如下表格形式完成. 本文为干货,希望有用,欢迎评论. 由于我的labtop上安装的是ubuntu16.04系统,其

算法导论笔记2 - T(n) = O(n) 的最大子数组问题解法

import random __author__ = 'Administrator' LENGTH = 500 base = [] for i in range(0, LENGTH * 2): base.append(random.randint(-1 * LENGTH, LENGTH)) print(base) bsa_i = 0 bsa_j = 1 bsa = base[0] bord = base[0] bord_i = 0 for i in range(1, len(base)): if

最大子数组乘积算法

给出一数组a,求最大子数组乘积 算法思路:用动态垃规划.用maxValue(n)表示从0到n的最大子数组乘积,minValue(n)表示从0到n的最小子数组乘积. 状态转移方程为: minValue(n)= min{minValue(n-1)*a[n], maxValue(n-1)*a[n], a[n]} maxValue(n)=max{minValue(n-1)*a[n], maxValue(n-1)*a[n], a[n]} 在求取最大子数组乘积时,更新最大值结果. 代码如下: class S

【LeetCode-面试算法经典-Java实现】【053-Maximum Subarray(最大子数组和)】

[053-Maximum Subarray(最大子数组和)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Find the contiguous subarray within an array (containing at least one number) which has the largest sum. For example, given the array [?2,1,?3,4,?1,2,1,?5,4], the contiguous subarra

【算法设计-分治】最大子数组问题

1.问题描述 算法导论上38页,最大子数组给出一组数组来,然后求出使得从i到j的数组值的和最大的边界i与j.如果不用分治的方法的话,需要通过暴力方法来寻找n(n-1)/2种. 方法: 2代码: #include<iostream> using namespace std; typedef struct maximum { int left; int right; int sum; }Maximum; Maximum* FIND_MAX_CROOSING_SUBARRAY(int *A,int

(算法)最大子数组和以及最大子矩阵和

题目: 1.给定一数组,求该数组的最大子数组和: 2.给定一矩阵,求该矩阵的最大子矩阵和: 思路: 1.求数组的最大子数组和很简单,可以通过动态规划来实现,假设数组为arr: 假设dp[i]表示从0到i的数组的最大子数组和,那么递推关系式表示为: dp[0]=arr[0]; dp[i]=dp[i-1]>0?dp[i-1]+arr[i]:arr[i] 2.求矩阵的最大子矩阵和看似很难,其实也可以转化为最大子数组和的问题.假设矩阵为matrix 首先,我们求出矩阵每个位置按行叠加的结果,设叠加结果矩

算法导论4.1寻找最大子数组

寻找最大子数组 // find_max_sub_array.h #include <stdint.h> int Find_MAX_CROSSING_SUBARRAY(int* A, int low, int mid, int high, int& max_left, int& max_right, int& max_value) { int left_sum = 0xFFFFFFFF; // 不可能的最小值 int sum = 0; for(int i = mid; i