寻找数组的中心索引(C++)

力扣的第1991题——寻找数组的中心索引
附链接:https://leetcode-cn.com/problems/find-the-middle-index-in-array/

题目描述:
给你一个整数数组 nums ,请计算数组的 中心下标 。

数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。

如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。

如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。

示例 1:
输入:nums = [1, 7, 3, 6, 5, 6]
输出:3
解释:
中心下标是 3 。
左侧数之和 sum = nums[0] + nums[1] + nums[2] = 1 + 7 + 3 = 11 ,
右侧数之和 sum = nums[4] + nums[5] = 5 + 6 = 11 ,二者相等。

示例 2:
输入:nums = [1, 2, 3]
输出:-1
解释:
数组中不存在满足此条件的中心下标。

示例 3:
输入:nums = [2, 1, -1]
输出:0
解释:
中心下标是 0 。
左侧数之和 sum = 0 ,(下标 0 左侧不存在元素),
右侧数之和 sum = nums[1] + nums[2] = 1 + -1 = 0 。

提示:

1 <= nums.length <= 104
-1000 <= nums[i] <= 1000

下面提供的代码都是完整的代码

先说说我一开始的想法,看到这题我的第一反应是双指针,因为我没注意到是整数或者说是我默认了整数就是正整数,写完代码测试数据时候发现数据可以有负数,而当出现负数时候就可能会出错。

但是,当数据都是正整数时候是可以使用双指针的,思路是谁小谁动,下面是代码(注释部分解释了为什么此题双指针是错误的):

class Solution {
public:
    int pivotIndex(vector<int>& nums) {   
	    int i = 0, j = nums.size() - 1;
    	int suml = nums[i], sumr = nums[j];
	    while (i + 2 < j)
	    {
	    	if (suml >= sumr)  //若目前左侧和大于等于右侧和(等于放在这里是为了保证当有多个中心下标时是最左侧的一个中心下标),则右指针应该向左侧移动一个位置,并加上当前元素,使右侧和变大(这里也就是为什么负数存在会出错的原因了,因为负数的存在使得指针移动时不一定使得和变大)
	    	{
	    		j--;
	    		sumr += nums[j];
	    	}
	    	else  //若是右侧和大于等于左侧,则左指针移动
	    	{
	    		i++;
	    		suml += nums[i];
	    	}
	    }
    	if (suml != sumr)  return -1;
	    else return i + 1;
    }
};

下面我们来说一说一个正解:
既然中心下标左右两侧之和相同,是不是可以转化为左侧之和的2倍加上中心元素等于所有元素之和呢
代码:

class Solution {
public:
    int pivotIndex(vector<int>& nums) {
        int sum = 0;  //所有元素之和
        int suml = 0;  //左侧元素和
        for (int i = 0; i < nums.size(); i++)  sum += nums[i];
        for (int i = 0; i < nums.size(); i++)
        {
            if (sum - nums[i] == suml * 2)  return i;
            else suml += nums[i];
        }
        return -1;
    }
};

感谢阅读!!!


你可能感兴趣的:(c++,leetcode,算法)