• 现代程序设计 作业 第1次


      首先向老师表示歉意,由于误记了截止时间,作业提交迟到了3小时,十分抱歉。

      在第一周选课期间,我还没有决定选取该门课程,所以并未出席第一次课,也没有提交课堂作业。于是,我在同学的描述下得知了本次的题目。

      本次作业的题目是:最大子数组之和。即在一个数组中求得连续子串和的最大值。

      思考这个问题时,我首先想到的是动态规划。但是动态规划更适用于求子串位置的问题,本题目并不要求,所以可以有更简便的解法。如果使用穷举法,时间复杂度为O(n2),而使用动态规划,时间复杂度为O(nlogn)。虽然时间复杂度较小,但是递归算法的空间复杂度将会更高,这并不划算。所以我首选了穷举法来解决这个问题,关键代码如下:

        for (i=0;i<n;i++){ 
            for(j=i,ctemp=0;j<n;j++){
                ctemp+=t[j];
                if(ctemp>max)
                    max=ctemp;
            }
        }

      这是一个简单的穷举法,从前到后穷举了每一个子串和,最终将最大值输出。

      不过这个程序还可以进一步改进。分析问题可以得知,具有最大和的子串的首尾元素不可能是负数。例如,如果是num[i]负数,则存在以num[i+1]为开头的更大子串。同理,以和为负的小子串开头的子串也必然是可以优化的。在网上查阅了一些资料后,我做出了以下优化:

        for (j=0; j<=i; j++){ 
            ctemp+=t[j]; 
            if (ctemp>max) 
                max=ctemp; 
            else if (ctemp<0) 
                ctemp=0; 
           }

      该段代码是在上一段基础之上的改进。其原理在于,通过排除负开头数字/子串的方式,节约了第一个for循环,从而将复杂度降低至O(n)的线性水平。

      不过此时也产生了一个例外情况:输入元素均为负值。那么还要增添一个判断条件,如果元素均为负,则最大子串和等于最大元素的值。

      以上为该次作业的全部讨论。

      另:我选择的教科书为 中文版 代码大全 (第二版)

  • 相关阅读:
    springmvc,springboot单元测试配置
    uboot中ftd命令
    在根文件系统中查看设备树(有助于调试)
    协议类接口
    网络设备接口
    块设备驱动框架
    i2c子系统
    触摸屏
    input子系统
    原子访问、自旋锁、互斥锁、信号量
  • 原文地址:https://www.cnblogs.com/libcan/p/3330464.html
Copyright © 2020-2023  润新知