《六月集训》第八日——前缀和

前言

这是五月集训的第日,今日的训练内容是 前缀和

解题报告

1.力扣1480

原题链接

https://leetcode-cn.com/problems/running-sum-of-1d-array/

题目概述

给你一个数组 nums 。数组「动态和」的计算公式为:runningSum[i] = sum(nums[0]…nums[i]) 。

请返回 nums 的动态和。

解题思路

为需要返回的数组进行内存申请,然后数组 ret[] 的每一项其实都等于 nums[] 中的当前项加上数组 ret[] 的上一项,这样复杂度就只有 O(n) 了。

源码剖析

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* runningSum(int* nums, int numsSize, int* returnSize){
    int i;
    int *ret = (int *)malloc( numsSize * sizeof(int) );
    for(i = 0; i < numsSize; ++i) {    // (1)
        ret[i] = nums[i];
        if(i) {
            ret[i] += ret[i-1];                      
        }
    }
    *returnSize = numsSize;
    return ret;
}

2.力扣1588

原题链接

https://leetcode-cn.com/problems/sum-of-all-odd-length-subarrays/

题目概述

给你一个正整数数组 arr ,请你计算所有可能的奇数长度子数组的和。

子数组 定义为原数组中的一个连续子序列。

请你返回 arr 中 所有奇数长度子数组的和 。

解题思路

直接使用暴力的遍历,把所有的满足条件的数组和全都统计最后返回。

源码剖析

int sumOddLengthSubarrays(int* arr, int arrSize){
    int i,j,k;
    int sum = 0;
    for(i=0;i<arrSize;++i){
        sum+=arr[i];
    }
    if(arrSize<=2) return sum;
    for(j=3;j<=arrSize;j=j+2){
        for(i=0;i<=arrSize-j;++i){
            for(k=i;k<i+j;++k){
                sum+=arr[k];
            }
        }
    }
    return sum;
}

3.力扣1442

原题链接

https://leetcode-cn.com/problems/count-triplets-that-can-form-two-arrays-of-equal-xor/

题目概述

给你一个整数数组 arr 。

现需要从数组中取三个下标 i、j 和 k ,其中 (0 <= i < j <= >k < arr.length) 。

a 和 b 定义如下:

a = arr[i] ^ arr[i + 1] ^ … ^ arr[j - 1]
b = arr[j] ^ arr[j + 1] ^ … ^ arr[k]
注意:^ 表示 按位异或 操作。

请返回能够令 a == b 成立的三元组 (i, j , k) 的数目。

解题思路

首先定义一个数组用来存储原来数组中的每一位置异或上前面每一项的值(也就是异或的前缀和),这里有一个特殊的处理手段,这个数组的容量比原来的数组的容量要多上1,在 0 的位置储存的是数字 0 因为任何的数字异或了零之后的数值是不发生改变的。用这个数组记录下所有的异或前缀和。然后枚举一个 k,枚举从 i+1 到数组末位,这里使用了一个思路,如果 a=b 也就是说明 a^b=0 那么也就是说 ik 项的异或前缀和都是 0 那么 i 项前的异或前缀和也就等于 k+1 项的异或前缀和,于是我们可以得出,当前 i 项前缀和和等于前 k+1 项前缀和的时候,a=b 就是成立的,那么其中的 j 随便取什么数都是无所谓的了,没取一种数也就对应一个三元祖,最后累加就可以得到答案了。

源码剖析

int countTriplets(int* arr, int arrSize){
    int sum[arrSize + 1];
    int i, k;
    int res = 0;
    sum[0] = 0;
    /* 异或的前缀和 */
    for (i = 1; i <= arrSize; i++) {
        sum[i] = arr[i - 1] ^ sum[i - 1];
    }
    for (i = 0; i < arrSize; i++) {
        for (k = i + 1; k < arrSize; k++) {
            if (sum[i] == sum[k + 1]) {
                res += k - i;   /* j的取值为[i+1, k] */
            }
        }
    }
    return res;
}

4.力扣1094

原题链接

https://leetcode-cn.com/problems/car-pooling/

题目概述

车上最初有 capacity 个空座位。车 只能 向一个方向行驶(也就是说,不允许掉头或改变方向)

给定整数 capacity 和一个数组 trips ,  trip[i] = [numPassengersi, fromi, toi] 表示第 i 次旅行有 numPassengersi 乘客,接他们和放他们的位置分别是 fromi 和 toi 。这些位置是从汽车的初始位置向东的公里数。

当且仅当你可以在所有给定的行程中接送所有乘客时,返回 true,否则请返回 false。

解题思路

此题暂时做记录,日后再来思考。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值