前缀和/前缀和+后缀和?!!:瞬秒Leetcode 742.寻找数组的中心下标

2024-03-05 02:28

本文主要是介绍前缀和/前缀和+后缀和?!!:瞬秒Leetcode 742.寻找数组的中心下标,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目

给你一个整数数组 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 。

阅读题目求一个下标左右两边和是否相等,一眼顶真前缀和没跑,接下来分为两个思路来解决此问题:解法一中规中矩使用完全的前缀和来解决,解法二使用前缀和加后缀和更加需要对前缀和思想有深刻的理解

前缀和思路

前缀和是什么:前缀和一镜到底:秒懂一、二维前缀和的逻辑与实现方式

首先可以构建名为dp的前缀和数组,这样比起每次都去暴力的遍历判断节省不少的时间,因为此时原生数组的下标是从0开始的,所以不能直接套用一维前缀和模板,而是先要对其进行处理,得出符合此题的动态转移方程,dp[1]所对应的是nums[0],所以dp[i]=dp[i-1]+nums[i-1]。

题目要求求判断i之前和之后是否相等,而求i之前的和只需要直接查找dp[i-1]就可以得到,查找i之后的只需要拿dp[n]-dp[i]就可以得到。

所以此题的使用公式为:dp[i-1]==dp[n]-dp[i];

代码实现

class Solution {
public:int pivotIndex(vector<int>& nums) {vector<int> dp(nums.size()+1);int ret=0,n=nums.size();//构建前缀和数组for(int i=1;i<=nums.size();i++){dp[i]=dp[i-1]+nums[i-1];}//使用前缀和数组for(int i=1;i<=nums.size();i++){if(dp[i-1]==dp[n]-dp[i]) return i-1;}return -1;}
};

前缀和+后缀和思路

除了直接通过前缀和数组进行减法操作后得出i之前和之后的数来判断是否相等以外,还可以在构建前缀和数组时就直接构建出俩个数组,一个记录每个节点左边的所有元素之和就是前缀和,一个记录每个节点右边的所有元素的和,构建好后只需要一次遍历从左往右遍历时比较两棵树对应的值就能找到最左符合要求的节点。

注意这里的每个节点存的时它之前的数的和,所以当前节点存的数是不包含nums数组中相对应的该位置的数的,而且此时所构建的前后缀和数组下标是直接从0开始的而题目说最靠左或右的左或右的和都为零,所以此时需要处理一下边界,所以前缀和数组0的位置赋值为0,后缀和n-1的位置赋值为0。然后构造数组时直接从第二个元素开始构造。从而得出前缀和的公式:

dpf[i]=dp[i-1]+nums[i-1];

后缀和公式:

dpe[i]=dpe[i+1]+dpe[i+1];

然后直接遍历进行比较就可以。

代码实现

class Solution {
public:int pivotIndex(vector<int>& nums) {vector<int> dpf(nums.size()),dpe(nums.size());dpf[0]=0;dpe[nums.size()-1]=0;for(int i=1;i<nums.size();i++)//构造前缀和数组{dpf[i]=dpf[i-1]+nums[i-1];}for(int i=nums.size()-2;i>=0;i--)//构造后缀和数组{dpe[i]=dpe[i+1]+nums[i+1];}for(int i=0;i<nums.size();i++){if(dpf[i]==dpe[i]) return i;}return -1;}
};

这篇关于前缀和/前缀和+后缀和?!!:瞬秒Leetcode 742.寻找数组的中心下标的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/775031

相关文章

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

跨国公司撤出在华研发中心的启示:中国IT产业的挑战与机遇

近日,IBM中国宣布撤出在华的两大研发中心,这一决定在IT行业引发了广泛的讨论和关注。跨国公司在华研发中心的撤出,不仅对众多IT从业者的职业发展带来了直接的冲击,也引发了人们对全球化背景下中国IT产业竞争力和未来发展方向的深思。面对这一突如其来的变化,我们应如何看待跨国公司的决策?中国IT人才又该如何应对?中国IT产业将何去何从?本文将围绕这些问题展开探讨。 跨国公司撤出的背景与

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

寻找身高相近的小朋友

题目描述: 小明今年升学到小学一年级,来到新班级后发现其他小朋友们身高参差不齐,然后就想基于各小朋友和自己的身高差对他们进行排序,请帮他实现排序。 输入描述: 第一行为正整数H和N,0<H<200,为小明的身高,0<N<50,为新班级其他小朋友个数。第二行为N个正整数H1-HN,分别是其他小朋友的身高,取值范围0<Hi<200(1<=i<=N),且N个正整数各不相同。 输出描述: 输出

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点