这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战
前言
解法
-
这道题很简单,意思就是一个数组分成两个部分,左边的部分和大于右边的部分和,找出这个界限,当然还有个问题可能界限在数组两边,例子里有写。
-
一开始我的想法收到的双指针的影响,想要在左右两边都设置一个指针然后开始累加,后面想想有界限在数组两端这种情况就很麻烦。
-
然后通过题解,我理解了这个解法
-
第一步,首先将数组都加起来,设置为sum
-
第二步,将索引0设置为界限,左边total加上这个界限,跟sum比,如果相等就返回,不相等就接着遍历,并且,total加上数组 的值,sum减去数组的值
-
第三步,当两边相等,返回索引
-
第四步,如果遍历完成返现没有相对应的数字,就返回-1
-
这道题算是入门,有一丝丝前缀和的味道,这道题还是相当简单的,不说了上代码
class Solution {
public int pivotIndex(int[] nums) {
//累加
int sum = Arrays.stream(nums).sum();
//左边
int total = 0;
int l = nums.length;
//循环遍历
for(int i=0;i<l;i++){
//加上当下的索引
total += nums[i];
if(total == sum){
return i;
}
//减去当下的索引
sum -= nums[i];
}
//没有合适的返回
return -1;
}
}
空间优化
- 甚至可以不使用额外空间。
- 先求一遍总和 total,再使用 sum 记录当前遍历位置的左侧总和。
- 对于中心索引必然有:sum = total - sum - nums[i] (左边值 = 右边值)
代码:
class Solution {
public int pivotIndex(int[] nums) {
int n = nums.length;
int total = 0, sum = 0;
// 我们的 nums 处理不涉及并行操作,使用循环要比 Arrays.stream 快
// total = Arrays.stream(nums).sum();
for (int i = 0; i < n; i++) total += nums[i];
for (int i = 0; i < n; i++) {
if (sum == total - sum - nums[i]) return i;
sum += nums[i];
}
return -1;
}
}
- 时间复杂度:对数组进行线性扫描。复杂度为 O(n)O(n)
- 空间复杂度:O(1)O(1)
总结
题目相当简单,但是很多难的算法都是从简单到复杂的,又一个循序渐进的过程,如果还想深入可以去看看变式,加油吧。