• 笔试算法题(06):最大连续子数组和 & 二叉树路径和值


    出题:预先输入一个整型数组,数组中有正数也有负数;数组中连续一个或者多个整数组成一个子数组,每个子数组有一个和;求所有子数组中和的最大值,要求时间复杂度O(n);

    分析:

    • 时间复杂度为线性表明只允许一遍扫描,当然如果最终的最大值为0表明所有元素都是负数,可以用线性时间O(N)查找最大的元素。具体算法策略请见代码和注释;
    • 子数组的起始元素肯定是非负数,如果添加的元素为正数则记录最大和值并且继续添加;如果添加的元素为负数,则判断新的和是否大于0,如果小于0则以下一个元素作为起始元素重新开始,如果大于0并且比最大和值小则不更新最大和值,并且继续添加元素;
    • 当然还有分治的解法,将数组分成A和B两个部分,则子数组最大和有三种可能,来自A,来自B和来自A和B的跨界处,时间复杂度为O(NlogN);
    • 如果数组为循环数组,则说明子数组最大和允许出现在array[n-1]和array[0]作为一部分的组合。这样题目分解为两个子题目,一个子题目就是 目标值没有跨过array[n-1]和array[0],其实也就是原来的题目;另一个子题目就是目标值为array[i]到array[n-1]和 array[0]到array[j]的组合,时间复杂度仍旧为O(N);

    解题:

     1 /**
     2  * 子数组累加和必定是从非负数的元素开始
     3  * 如果子数组和小于0则缺省最大值为0
     4  * */
     5 int MaxSubArray(int *array, int count) {
     6         int max=0;
     7         int curMax=0;
     8         for(int i=0;i<count;i++) {
     9                 curMax+=array[i];
    10                 /**
    11                  * 跳过负数元素,所以目标子数组必定以非负数元素开始
    12                  * */
    13                 if(curMax < 0) {
    14                         curMax=0;
    15                         continue;
    16                 }
    17                 /**
    18                  * 一旦遇到负数元素,除当前负数元素的其他元素的和作为
    19                  * 最大值;由于不能保证之后的元素不会让子数组和变得更大
    20                  * ,所以累加继续
    21                  * */
    22                 if(array[i]<0) {
    23                         if(max<(curMax-array[i])) {
    24                                 max=curMax-array[i];
    25                         }
    26                 } else {
    27                         if(max<curMax) {
    28                                 max=curMax;
    29                         }
    30                 }
    31         }
    32         return max;
    33 }
    34 
    35 int MaxDif(int *array, int length) {
    36         /**
    37          * 定义局部stack数组存储相邻元素差值
    38          * 循环获取相邻元素差值
    39          * */
    40         int difarray[length-1];
    41         for(int i=0;i<length-1;i++) {
    42                 difarray[i]=array[i]-array[i+1];
    43                 printf("
    %d",difarray[i]);
    44         }
    45         /**
    46          * sum记录最大和值
    47          * tempsum记录当前元素的和值
    48          * 如果元素为+++++++,则从开始相加到最后
    49          * 如果元素为-------,则sum保持为0
    50          * 如果元素为++++---,则sum保持为前半正数
    51          * 如果元素为----+++,则sum保持为后半正数
    52          * 还有其他满足条件的情况
    53          * */
    54         int tempsum=0, sum=0;
    55         for(int i=0;i<length-1;i++) {
    56                 tempsum+=difarray[i];
    57                 if(tempsum<0)
    58                         tempsum=0;
    59                 else if(tempsum>sum)
    60                         sum=tempsum;
    61         }
    62         return sum;
    63 }
    64 
    65 
    66 int main() {
    67         int array[]={1,-2,3,10,-4,-7,-2};
    68         printf("the max sub array sum: %d",MaxSubArray(array,7));
    69         return 1;
    70 }

    出题:输入一个整数和一颗二元树(节点值为整数),从树的根节点开始往下访问每一个节点,直到叶子节点最终形成一条路径。打印出所有节点和与整数值相等路径;

    分析:深度优先搜索,使用Stack结构记录路径;

    解题:

     1 /**
     2  * 使用path记录路径
     3  * */
     4 void SpecialDfs(Node *current, MyStack *path, int sum, int target) {
     5         path->push(current->value);
     6         sum+=current->value;
     7         bool isLeaf=true;
     8 
     9         if(current->left != NULL) {
    10                 SpecialDfs(current->left, path, sum, target);
    11                 isLeaf=false;
    12         }
    13 
    14         if(current->right != NULL) {
    15                 SpecialDfs(current->right, path, sum, target);
    16                 isLeaf=false;
    17         }
    18 
    19         if(isLeaf && sum == target) {
    20                 path->showStack();
    21         }
    22         path->pop(NULL);
    23 }
  • 相关阅读:
    "rel=nofollow"属性简介
    js获取微信code
    css--clearfix浮动
    css3--之HSL颜色
    数据库列名为关键字如何搜索
    flexigrid
    easyui-dialog
    关于在jsp中的表达式
    jquery 中 $('div','li')
    myeclipse中常用的快捷键
  • 原文地址:https://www.cnblogs.com/leo-chen-2014/p/3732391.html
Copyright © 2020-2023  润新知