Coding | [代码随想录][数组] 58.区间和 44.开发商购买土地

难以接受的是这本应该在大一大二就逐渐经历的coding & debugging经历我居然到大三下才接触到。真是羞耻

第一想法确实是遇到一个区间就在数组中累加。很通人性的想法。

#include <stdio.h>
#include <stdlib.h>
 
int IntervalSum(int* arr, int left, int right);
 
int main(){
    int arraysize;
    scanf("%d", &arraysize);
    // printf("arraysize = %d\n", arraysize);
    int* arr = (int*)malloc(sizeof(int) * arraysize);
    for(int i = 0; i < arraysize; i++){
        scanf("%d", &arr[i]);
        // printf("ith arr_element = %d ", arr[i]);
    }
    int left, right;
    while(scanf("%d %d", &left, &right) == 2){
        int ans = IntervalSum(arr, left, right);
        printf("%d\n", ans);
    }
    return 0;
}
 
int IntervalSum(int* arr, int left, int right){
    int int_sum = 0;
    for(int k = left; k <= right; k++){
        int_sum += arr[k];
    }
    return int_sum;
}
/**************************************************************
    Problem: 1070
    User: odCYZ6rIpK_ZEEth56_tjfAkOnvg [kamaCoder567695]
    Language: C
    Result: 正确
    Time:793 ms
    Memory:1584 kb
****************************************************************/

后来我参考了前缀和的想法,新建了一个数组空间存储上前缀和进而计算出结果。

#include <stdio.h>
#include <stdlib.h>
 
int IntervalSum(int *arr, int left, int right, int size);
 
int main() {
  int arraysize;
  scanf("%d", &arraysize);
  // printf("arraysize = %d\n", arraysize);
  int *arr = (int *)malloc(sizeof(int) * arraysize);
  for (int i = 0; i < arraysize; i++) {
    scanf("%d", &arr[i]);
    // printf("ith arr_element = %d ", arr[i]);
  }
  int left, right;
  while (scanf("%d %d", &left, &right) == 2) {
    int ans = IntervalSum(arr, left, right, arraysize);
    printf("%d\n", ans);
  }
  return 0;
}
 
int IntervalSum(int *arr, int left, int right, int size) {
  int* prefix_sum = (int*)malloc(sizeof(int) * size);
  int prefix = 0;
  for (int j = 0; j < size; j++){
    prefix_sum[j] = prefix;
    prefix += arr[j];
  }
  prefix_sum[size] = prefix;
  int ans = prefix_sum[right+1] - prefix_sum[left];
  return ans;
}
/**************************************************************
    Problem: 1070
    User: odCYZ6rIpK_ZEEth56_tjfAkOnvg [kamaCoder567695]
    Language: C
    Result: 内存超限
****************************************************************/

想必是新建数组带来了不必要的内存占用,相当于导致了原来的两倍了。

改变策略,我想要实现在原数组上直接修改。但是这个修改操作本身会遇到些许问题,比如:修改应该是从后往前的,否则会导致前后不一致;从后往前需要提前知道整个数组的总和,但是如何得来?为了不增加时间复杂度,也是想到在 scanf 的时候就将数组的总和计算出来。

虽然这样说出来我自己都感觉得到这些操作其实很低端,但是这样的经历到大三我才开始遭遇。

Once again, shame on me.

最后debug一番得到了时间和空间复杂度在我认知范围内最好的算法。

#include <stdio.h>
#include <stdlib.h>
 
int main() {
    // input operation
    int arraysize;
    int sum_all = 0;
    scanf("%d", &arraysize);
    int *arr = (int *)malloc(sizeof(int) * arraysize);
    for (int i = 0; i < arraysize; i++) {
    scanf("%d", &arr[i]);
    sum_all += arr[i];
    }

    // re-build a prefix_sum_array **right at the original array's address**
    int left, right;
    int prefix = 0;
    for (int k = arraysize - 1; k >= 0; k--) {
    int temp = arr[k];
    arr[k] = sum_all;
    sum_all -= temp;
    }

    // compute the ans
    while (scanf("%d %d", &left, &right) == 2) {
    int ans;
    if(left != 0){
        ans = arr[right]- arr[left-1];
    }
    else{
        ans = arr[right];
    }
    printf("%d\n", ans);
    }

    return 0;
}

同样的前缀和思路,也是成功地自己实现出了进阶版本的区间和——44.开发商购买土地

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

int main(){
    // input operation
    int col, row;
    scanf("%d %d", &row, &col);

    int* row_sum = (int*)malloc(sizeof(int) * row);
    int* col_sum = (int*)malloc(sizeof(int) * col);
    int all_sum = 0;
    for(int i = 0; i < row; i++){
        for(int j = 0;  j < col; j++){
            int temp;
            scanf("%d", &temp);
            row_sum[i] += temp;
            col_sum[j] += temp;
            all_sum += temp;
        }
    }

    // for(int i = 0; i < row; i++){
    //     printf("%d ", row_sum[i]);
    // }
    // printf("\n");
    // for(int j = 0; j < col; j++){
    //     printf("%d ", col_sum[j]);
    // }
    // printf("\n");

    // re-build prefix-sum arrays
    int all_sum_row = all_sum;
    int all_sum_col = all_sum;
    for(int k = row-1; k >= 0; k--){
        int temp_k = row_sum[k];
        row_sum[k] = all_sum_row;
        all_sum_row -= temp_k;
    }
    for(int m = col-1; m >= 0; m--){
        int temp_m = col_sum[m];
        col_sum[m] = all_sum_col;
        all_sum_col -= temp_m;
    }

    // for(int i = 0; i < row; i++){
    //     printf("%d ", row_sum[i]);
    // }
    // printf("\n");
    // for(int j = 0; j < col; j++){
    //     printf("%d ", col_sum[j]);
    // }
    // printf("\n");

    // discuss the row-wise situation
    int res_row = all_sum;
    for(int wall_row = 0; wall_row < row-1; wall_row++){
        int temp_row = row_sum[row-1] > 2*row_sum[wall_row] ? row_sum[row-1] - 2*row_sum[wall_row] : 2*row_sum[wall_row] - row_sum[row-1];
        res_row = res_row < temp_row ? res_row : temp_row;
    }

    // discuss the rol-wise situation
    int res_col = all_sum;
    for(int wall_col = 0; wall_col < col-1; wall_col++){
        int temp_col = col_sum[col-1] > 2*col_sum[wall_col] ? col_sum[col-1] - 2*col_sum[wall_col] : 2*col_sum[wall_col] - col_sum[col-1];
        res_col = res_col < temp_col ? res_col : temp_col;
    }

    int res = res_col < res_row ? res_col : res_row;
    printf("%d", res);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值