早起跟着英雄哥刷算法--day1

提示:本文参考英雄哪里出来的文章,原文连接⭐算法入门⭐《前缀和》简单01 —— LeetCode 724. 寻找数组的中心下标


一、题目

给定一个整数 数组 nums,请计算数组的中心下标 。数组中心下标是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1。
样例输入:nums = [1, 7, 3, 6, 5, 6]
样例输出:3

原题链接:

LeetCode 724. 寻找数组的中心下标
LeetCode 剑指 Offer II 012. 左右两边子数组的和相等


二、解题思路

1.大致思路

  1. 前缀和的计算公式:sum[i] = nums[i] + sum[i-1]
  2. 当遍历到第i个元素的时候,设其左侧元素之和为 s u m sum sum, 其右侧元素之和为 t a t a l − n u m s i − s u m tatal - nums_{i}- sum tatalnumsisum
  3. 左右元素相等即为 s u m = t a t a l − n u m s i − s u m sum = tatal - nums_{i}- sum sum=tatalnumsisum, 即 s u m ∗ 2 + n u m s i = t o t a l sum * 2 + nums_{i} = total sum2+numsi=total
  4. 当中心索引左侧或右侧没有元素时,即为零个项相加,这在数学上称作「空和」(empty suml)。在程序设计中我们约定「空和是零」。

2.代码实现

(1)第一次通过:

#define maxn 100010

class Solution {
    int sum[maxn];
public:
    int pivotIndex(vector<int>& nums) {
        int numsSize = nums.size();
        int i;
	    for(i = 0; i < numsSize; ++i) {
	        sum[i] = nums[i];
	        if(i) 
	            sum[i] += sum[i-1];        // (1) 
	    }
	    if(sum[numsSize-1] - sum[0] == 0) {
	        return 0;                      // (2) 
	    }
	    for(i = 1; i < numsSize; ++i) {
	        if( sum[i-1] == sum[numsSize-1] - sum[i] ) {
	            return i;                  // (3) 
	        }
	    }
	    return -1;                         // (4)
    }
};
  • (1) 计算前缀和;
  • (2) 考虑中心下标在 0 的情况;
  • (3) 左边的部分和为sum[i-1],右边的部分和为sum[numsSize-1] - sum[i]
  • (4) 找不到中心坐标的情况,直接返回 -1;

(2)第二次改进

简化判断条件,将中心索引左侧或右侧为空值的情况利用 s u m ∗ 2 + n u m s i = t o t a l sum * 2 + nums_{i} = total sum2+numsi=total 一起表示出来,减少一次判断。
代码参考:寻找数组的中心索引

class Solution {
public:
    int pivotIndex(vector<int> &nums) {
        int total = accumulate(nums.begin(), nums.end(), 0);
        int sum = 0;
        for (int i = 0; i < nums.size(); ++i) {
            if (2 * sum + nums[i] == total) {
                return i;
            }
            sum += nums[i];
        }
        return -1;
    }
};

(3)复杂度分析

时间复杂度: O ( n ) O(n) O(n),其中 n n n 为数组的长度。
空间复杂度: O ( 1 ) O(1) O(1)

总结

对前缀和的概念及其运用有了初步的了解,使用于此类计算中心下标的题目
若使用暴力直接求解,时间复杂度将变为 O ( n 2 ) O(n^2) O(n2),先求得前缀和数组再进行循环比对,可将时间复杂度降至 O ( n ) O(n) O(n)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值