算法导论第4章习题解析

4.1-1 当A的所有元素均为负数,FIND-MAXMUM-SUBARRAY返回的是A中第一个最大值。

4.1-2 代码如下:

#include<stdlib.h>
#include<stdio.h>

int* find_maximum_subarray_violence(int* A,int length){
    int* retArray = (int*)malloc(3 * sizeof(int));

    int max_sum = A[0];
    int temp_sum = 0;
    int left = 0;
    int right = 0;

    for(int i = 0; i < length - 1; i++){
        temp_sum = A[i];      
        for(int j = i + 1; j < length; j++){
            temp_sum += A[j];
            if(temp_sum > max_sum){
                max_sum = temp_sum;
                left = i;
                right = j;
            }
        }
    }

    retArray[0] = left;
    retArray[1] = right;
    retArray[2] = max_sum;

    return retArray;
}

int main(){
    int A[] = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};
    int* retArray = find_maximum_subarray_violence(A,15);
    printf("%d,%d,%d",retArray[0], retArray[1], retArray[2]);
    return 0;
}

4.1-3:略

4.1-4:修改后的代码如下:

#include<stdio.h>
#include<limits.h>
#include<stdlib.h>

int* find_max_crossing_subarray(int* a,int low,int mid,int high){
    int *retArray= (int *)malloc(3 * sizeof(int));

    int max_left = -1;
    int max_right = -1;
    int left_sum = 0;
    int right_sum = 0;

    int temp_sum = 0;
    for(int i = mid;i >= low;i--){
        temp_sum += a[i];
        if(temp_sum > left_sum){
            left_sum = temp_sum;
            max_left = i;
        }
    }

    temp_sum = 0;
    for(int i = mid + 1; i <= high; i++){
        temp_sum += a[i];
        if(temp_sum > right_sum){
            right_sum = temp_sum;
            max_right = i;
        }
    }

    retArray[0] = max_left;
    retArray[1] = max_right;
    retArray[2] = left_sum + right_sum;

    return retArray;
}

//递归方式求解最大子数组问题
int* find_maximum_subarray(int* a,int low,int high){
    int *retArray= (int *)malloc(3 * sizeof(int));
    if(low == high){
        retArray[0] = low;
        retArray[1] = high;
        retArray[2] = a[low];
    }
    else{
            int mid = (low + high) / 2;
            int* ret_left = find_maximum_subarray(a, low, mid);
            int* ret_right = find_maximum_subarray(a, mid + 1, high);
            int* ret_middle = find_max_crossing_subarray(a, low, mid, high);
            if(ret_left[2] > ret_right[2] && ret_left[2] > ret_middle[2]){
                retArray[0] = ret_left[0];
                retArray[1] = ret_left[1];
                retArray[2] = ret_left[2];
            }
            else if(ret_right[2] > ret_left[2] && ret_right[2] > ret_middle[2]){
                retArray[0] = ret_right[0];
                retArray[1] = ret_right[1];
                retArray[2] = ret_right[2];
            }
            else{
                retArray[0] = ret_middle[0];
                retArray[1] = ret_middle[1];
                retArray[2] = ret_middle[2];
            }

    }
    return retArray;
}

int main(){
    int A[] = {-13, -3, -25, -20, -3, -16, -23, -18, -20, -7, -12, -5, -22, -15, -4, -7};    
    int* ret = find_maximum_subarray(A, 0, 15);
    printf("%d,%d,%d",ret[0],ret[1],ret[2]);
    return 0;
}

4.1-5

#include<stdio.h>
#include<stdlib.h>

int* find_maxiumu_subarray_Linear (int* A, int length){
    int left = 0;
    int right = 0;   
    int temp_sum = A[0];
    int max_sum = temp_sum;

    for (int j = 1; j < length; j++){
        temp_sum += A[j];
        if(max_sum < temp_sum){
            right = j;
            max_sum = temp_sum;
        }
        else{
            if(A[j] > temp_sum){
                left = j;
                right = j;
                temp_sum = A[j];
                max_sum = temp_sum;
            }
        }
    }    

    int* retArray = (int*)malloc(3 * sizeof(int));
    retArray[0] = left;
    retArray[1] = right;
    retArray[2] = max_sum;
    return retArray;
}

int main(){
    int A[] = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};   
    int* ret = find_maxiumu_subarray_Linear(A, 15);
    printf("%d,%d,%d",ret[0],ret[1],ret[2]);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值