Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述
- 给你一个整数数组
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 <= 10000-1000 <= nums[i] <= 1000
二、思路分析:
- 中心数有四种情况
- 第一种:数组第一位为中心数,可能后面有其他中心数
- 第二种:数组最后一位为中心数,可能前面有其他中心数
- 第三种:数组中间某一位或几位是中心数
- 第四种:数组没有中心数
- 这里定义了两个变量
left和right用来保存中心数左边和右边的和 - 第一种情况:
- 当数组第一位为中心数时,左边的和默认是
0,只需要将右边的和累加起来即可 - 遍历数组,去除掉当前数字本身,遍历参数应当从
1开始 - 如果累加后的左边和等于右边和,说明数组第一个值是中心数,因为可能有多个,先保存到数组变量中
- 当数组第一位为中心数时,左边的和默认是
- 第二种情况:
- 当数组最后一位为中心数时,右边的和默认是
0,只需要将左边的和累加起来即可 - 遍历数组,去除掉当前数字本身,遍历参数应当小于数组长度减去
1 - 如果累加后的左边和等于右边和,说明数组最后一个值是中心数,因为可能有多个,先保存到数组变量中
- 当数组最后一位为中心数时,右边的和默认是
- 第三种情况:
- 当数组中心数在中间某一项时,需要将数组的左边和右边分别统计出来
- 统计左边的和,范围应当是
0 ~ i并且包括i - 统计右边的和,范围应当是
i+1 ~ nums.length - 1 - 如果累加后的左边和等于右边和,说明当前项是中心数,因为可能有多个,先保存到数组变量中
- 第四种情况:
- 遍历完数组后,如果数组长度为
0,说明没有中心数,直接返回-1
- 遍历完数组后,如果数组长度为
- 其他:数组中有中心数,不管有几个,将数组升序排序,返回第一个值,即最小的中心数
三、AC 代码:
function pivotIndex(nums: number[]): number {
let result = [];
for(let i = 0; i < nums.length; i++){
let left = 0;
let right = 0;
if(i === 0) {
for(let j = 1; j < nums.length; j++){
right += nums[j];
}
if(right === left){
result.push(0);
break;
}
}
if(i === nums.length - 1){
for(let j = 0; j < nums.length - 1; j++){
left += nums[j];
}
if(right === left){
result.push(nums.length - 1);
break;
}
}
for(let l = 0; l < i; l++){
left += nums[l]
}
for(let r = nums.length - 1; r > i; r--){
right += nums[r]
}
if(right === left) result.push(i)
}
if(!result.length) return -1
result.sort((a, b) => { return a - b })
return result[0];
};
四、总结:
- 分好情况后还是比较简单的,当然还有其他复杂度低的方法,这里就不写了
- 更多解题方式,移步题解区