IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数据结构_1.基本概念_1.3应用实例:最大子列和问题 -> 正文阅读

[数据结构与算法]数据结构_1.基本概念_1.3应用实例:最大子列和问题

1.3 应用实例:最大子列和问题

1.3.1应用实例-算法1&2

给定N个整数的序列{ A 1 , A 2 . . . , A N A_1,A_2...,A_N A1?,A2?...,AN?},求函数 f ( i , j ) = m a x ( 0 , ∑ i = 1 n A k ) f(i,j)=max(0,\displaystyle\sum_{i=1}^{n} A_k) f(i,j)=max(0,i=1n?Ak?)的最大值

  • 算法1
int MaxSubseqSum1(int A[],int N){
    int ThisSum,MaxSum=0;
    int i,j,k;
    for(i=0;i<N;i++){//i是子列左端位置
        for(j=i;j<N;j++){//j是子列右端位置
            ThisSum=0;//ThisSum是从A[i]到A[j]的子列和
            for(k=i;k<=j;k++){
                ThisSum+=A[k];
            }
            if(ThisSum>MaxSum)//如果刚得到的这个子列和更大
                MaxSum=ThisSum;//则更新结果
        }
    }
return MaxSum;
}

时间复杂度 T ( N ) = O ( N 3 ) T(N)=O(N^3) T(N)=O(N3)
在K循环中浪费了大量的时间,当i不变,j++时,完全没必要从头算起,只需在已算出的ThisSum后再+j即可,故改进为算法2

  • 算法2
int MaxSubseqSum1(int A[],int N){
    int ThisSum=0,MaxSum=0;
    int i,j,k;
    for(i=0;i<N;i++){//i是子列左端位置
        for(j=i;j<N;j++){//j是子列右端位置
            ThisSum+=A[j];//对于相同的i,不同的j,只要在j-1次循环的基础上累加1项即可
            if(ThisSum>MaxSum)//如果刚得到的这个子列和更大
                MaxSum=ThisSum;//则更新结果
        }
    }
return MaxSum;
}

时间复杂度 T ( N ) = O ( N 2 ) T(N)=O(N^2) T(N)=O(N2)
一般 O ( N 2 ) O(N^2) O(N2)的复杂度,通过二分方法,都可以降到 n l o g n nlogn nlogn,故改进为算法3(分而治之)

1.3.2应用实例-算法3:分而治之

  • 算法3
    递归的思想
    在这里插入图片描述
  1. 把数组从中间一分为二,然后递归地去分别找出左右两边的最大子列和。
  2. 考虑跨越边界的最大子列和,即从中间开始,往左边扫描,然后往右边扫描
  3. 返回这三个结果中的最大值。

整个的时间复杂度 T ( N ) T(N) T(N),分成两半后,左右两边规模减半,即两边的时间复杂度都为 T ( N / 2 ) T(N/2) T(N/2)。中间的向左向右每个元素都扫描一次,所以中间的复杂度是N的一个常数倍 O ( N ) O(N) O(N)
故得到: ??? T ( N ) = 2 T ( N / 2 ) + c N , ?? T ( 1 ) = O ( 1 ) T(N)=2T(N/2)+cN, \ \ T(1)=O(1) T(N)=2T(N/2)+cN,??T(1)=O(1)
??? ???? 将N替换成N/2,再将 T ( N / 2 ) T(N/2) T(N/2)代入上式得:
??? ???? T ( N ) = 2 [ 2 ? T ( N / 2 2 ) + c N / 2 ] + c N T(N)=2[2\ T(N/2^2)+cN/2]+cN T(N)=2[2?T(N/22)+cN/2]+cN
? ??????? ???? = 2 2 ? T ( N / 2 2 ) + 2 c N =2^2\ T(N/2^2)+2cN =22?T(N/22)+2cN
? ??????? ???? = 2 k O ( 1 ) + c k N =2^kO(1)+ckN =2kO(1)+ckN? 其中 N / 2 K = 1 N/2^K=1 N/2K=1
这一步为展开直到T()里面的数到1为止,展开了k步后得到上面这个式子,其中 k = log ? 2 N k=\log_2^N k=log2N?,两项的复杂度分别为 O ( N ) , O ( N l o g N ) O(N),O(N logN) O(N),O(NlogN),两个复杂度相加取大的那个,故:
??? ???? T ( N ) = O ( N l o g N ) T(N)=O(NlogN) T(N)=O(NlogN)

int Max(int A, int B, int C)
{
    if (A > B) {
        if (A > C)
            return A;
        else
            return C;
    }
    else if (B > C)
        return B;
    else return C;
}

int DivideAndConquer(int List[], int left, int right) {
    int MaxLeftSum, MaxRightSum;
    int MaxLeftBoardSum, MaxRightBoardSum;
    int LeftBoardSum, RightBoardSum;
    int center,i;

    if (left == right) {/*递归终止条件*/
        if (List[left] > 0)
            return List[left];
        else
            return 0;
    }

    center = (right + left) / 2;
    MaxLeftSum = DivideAndConquer(List, left, center);
    MaxRightSum= DivideAndConquer(List, center+1, right);

    MaxLeftBoardSum = 0; 
    LeftBoardSum = 0;
    for (i = center;i >= left; i--)
        LeftBoardSum += List[i];
    if (LeftBoardSum > MaxLeftBoardSum)
        MaxLeftBoardSum = LeftBoardSum;
    
    MaxRightBoardSum = 0; 
    RightBoardSum = 0;
    for (i = center + 1; i <= right; i++)
        RightBoardSum += List[i];
    if (RightBoardSum > MaxRightBoardSum)
        MaxRightBoardSum = RightBoardSum;

    return Max(MaxLeftSum, MaxRightSum, MaxRightBoardSum + MaxLeftBoardSum);
}

int MaxSubseqSum3(int A[], int N)
{
    return DivideAndConquer(A, 0, N-1);
}

算法3的代码从博主CrownP的文章中学习得到

1.3.3应用实例-算法4:分而治之

int MaxSubsquSum4(int A[],int N){
    int ThisSum=0,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;
}

T ( N ) = O ( N ) T(N)=O(N) T(N)=O(N)
在线”的意思使指每输入一个数据就进行计时处理,在任何一个地方中止输入,算法都能正确给出当前的解。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章           查看所有文章
加:2021-08-07 21:48:54  更:2021-08-07 21:49:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 7:47:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码