【优选算法必刷100题】第027~28题(前缀和算法):寻找数组的中心下标、除自身以外数组的乘积

【优选算法必刷100题】第027~28题(前缀和算法):寻找数组的中心下标、除自身以外数组的乘积

🔥艾莉丝努力练剑:个人主页

专栏传送门:《C语言》《数据结构与算法》C/C++干货分享&学习过程记录Linux操作系统编程详解笔试/面试常见算法:从基础到进阶

⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平


🎬艾莉丝的简介:



🎬艾莉丝的算法专栏简介:


目录

​027  寻找数组的中心下标

 1.1  算法思路:前缀和

1.2  算法实现

1.2.1  C++实现

1.2.2  Java实现

1.3  博主手记

​028  除自身以外数组的乘积

2.1  算法思路

2.2  算法实现

2.2.1  C++实现

2.2.2  Java实现

2.3  博主手记

结尾


027  寻找数组的中心下标

力扣链接:724. 寻找数组的中心下标

力扣题解链接:前缀和优化法解决【寻找数组的中心下标】问题

题目描述:

 

1.1  算法思路:前缀和

我们根据中心下标的定义可知:除中心下标的元素外,该元素左边的前缀和】等于该元素右边的【后缀和】——

(1)因此,我们可以先预处理出来两个数组,一个表示前缀和,另一个表示后缀和。
(2)然后,我们可以用一个for循环枚举可能的中心下标,判断每一个位置的「前缀和」以及【后缀和】,如果二者相等,就返回当前下标。

1.2  算法实现

1.2.1  C++实现

代码演示如下——

class Solution { public: int pivotIndex(vector<int>& nums) { // 数组大小 int n = nums.size(); vector<int> f(n),g(n); // // 细节处理 // int f[0] = 0,g[n - 1] = 0; // 1、预处理前缀和数组和后缀和数组 for(int i = 1;i < n;i++) // f[0] = 0,如果i = 0开始会发生越界访问 f[i] = f[i - 1] + nums[i - 1]; for(int i = n - 2;i >= 0;i--) g[i] = g[i + 1] + nums[i + 1]; // 2、使用 for(int i = 0;i < n;i++) if(f[i] == g[i]) return i; return -1; } };
时间复杂度:O(n),空间复杂度:O(1)。

 

1.2.2  Java实现

代码演示如下——

class Solution { public int pivotIndex(int[] nums) { // lsum[i] 表示:[0, i - 1] 区间所有元素的和 // rsum[i] 表示:[i + 1, n - 1] 区间所有元素的和 int n = nums.length; int[] lsum = new int[n]; int[] rsum = new int[n]; // 预处理前缀和后缀和数组 for (int i = 1; i < n; i++) lsum[i] = lsum[i - 1] + nums[i - 1]; for (int i = n - 2; i >= 0; i--) rsum[i] = rsum[i + 1] + nums[i + 1]; // 判断 for (int i = 0; i < n; i++) if (lsum[i] == rsum[i]) return i; return -1; } }
时间复杂度:O(n),空间复杂度:O(1)。  

 

1.3  博主手记

本题整个的思路、算法原理、解题过程博主在纸上推导了一遍,大家可以参考一下手记的推导过程!最好做题的过程中自己也推导一遍!!!自己能够推导很重要!

 


​028  除自身以外数组的乘积

力扣链接:238. 除自身以外数组的乘积

力扣题解链接:前缀后缀乘积法解决【除自身以外数组的乘积】

题目描述:

 

2.1  算法思路

注意题目的要求,不能使用除法,并且要在O(N)的时间复杂度内完成该题。那么我们就不能使
用暴力的解法,以及求出整个数组的乘积,然后除以单个元素的方法。
继续分析,根据题意,对于每一个位置的最终结果ret[i],它是由两部分组成的:

(1)nums[0] * nums[1] * nums[2] *  ...  *nums[i - 1]
(2)nums[i + 1] * nums[i + 2] * ... * nums[n - 1]

于是,我们可以利用前缀和的思想,使用两个数组post和suf,分别处理出来两个信息:

(1)post表示:i位置之前的所有元素,即[0,i - 1]区间内所有元素的前缀乘积;
(2)suf表示:i位置之后的所有元素,即[i + 1,n - 1]区间内所有元素的后缀乘积然后再处理最终结果。

2.2  算法实现

2.2.1  C++实现

代码演示如下——

class Solution { public: vector<int> productExceptSelf(vector<int>& nums) { // lprod 表示:[0, i - 1] 区间内所有元素的乘积 // rprod 表示:[i + 1, n - 1] 区间内所有元素的乘积 int n = nums.size(); vector<int> lprod(n + 1), rprod(n + 1); lprod[0] = 1, rprod[n - 1] = 1; // 预处理前缀积以及后缀积 for (int i = 1; i < n; i++) lprod[i] = lprod[i - 1] * nums[i - 1]; for (int i = n - 2; i >= 0; i--) rprod[i] = rprod[i + 1] * nums[i + 1]; // 处理结果数组 vector<int> ret(n); for (int i = 0; i < n; i++) ret[i] = lprod[i] * rprod[i]; return ret; } };
时间复杂度:O(n),空间复杂度:O(1)。

2.2.2  Java实现

代码演示如下——

class Solution { public int[] productExceptSelf(int[] nums) { // lprod 表示:[0, i - 1] 区间内所有元素的乘积 // rprod 表示:[i + 1, n - 1] 区间内所有元素的乘积 int n = nums.length; int[] lprod = new int[n]; int[] rprod = new int[n]; lprod[0] = 1; rprod[n - 1] = 1; // 预处理前缀积以及后缀积 for (int i = 1; i < n; i++) lprod[i] = lprod[i - 1] * nums[i - 1]; for (int i = n - 2; i >= 0; i--) rprod[i] = rprod[i + 1] * nums[i + 1]; // 处理结果数组 int[] ret = new int[n]; for (int i = 0; i < n; i++) ret[i] = lprod[i] * rprod[i]; return ret; } }
时间复杂度:O(n),空间复杂度:O(1)。

2.3  博主手记

本题整个的思路、算法原理、解题过程博主在纸上推导了一遍,大家可以参考一下手记的推导过程!最好做题的过程中自己也推导一遍!!!自己能够推导很重要!


结尾

往期回顾:

【优选算法必刷100题】第025~26题(前缀和算法):【模版】前缀和、【模板】二维前缀和

结语:都看到这里啦!请大佬不要忘记给博主来个“一键四连”哦!

🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡

૮₍ ˶ ˊ ᴥ ˋ˶₎ა


Read more

排序算法的速度美学:快速排序深度漫游

排序算法的速度美学:快速排序深度漫游

目录 一、快速排序思想 二、Hoare版本 1、Hoare版本介绍 2、编码实操 3、时间复杂度分析 4、有序情况优化 4.1 随机选keyi 4.2 三数取中 小贴士: 5、稳定性分析 三、挖坑法 1、挖坑法介绍 2、编码实操 四、lomuto前后指针版本 1、前后指针版本介绍 2、编码实操 3、小区间优化 五、迭代版本(非递归) 1、递归的缺陷 2、非递归思路 3、编码实操 六、三路划分 1、三路划分思想 2、

By Ne0inhk

【YOLOv8+CAA+HSFPN】频率检测识别算法改进与实现_1

1. YOLOv8+CAA+HSFPN频率检测识别算法改进与实现 1.1. 摘要 本文针对频率检测识别任务中的复杂环境挑战,提出了一种基于YOLOv8的改进算法,结合通道注意力机制(CAA)和高效特征金字塔网络(HSFPN)。通过在骨干网络中引入CAA模块增强特征表达能力,并在特征融合阶段采用HSFPN结构,有效提升了模型对不同频率特征的捕捉能力。实验表明,改进后的算法在频率检测任务中mAP提升了3.2%,推理速度提高了15%,为实时频率信号处理提供了新思路。 1.2. 引言 频率检测识别在通信、雷达、声呐等领域具有广泛应用。传统方法如FFT、小波变换等在复杂环境下表现不佳,而深度学习方法虽然取得了一定进展,但仍面临特征提取不充分、计算效率低等问题。YOLOv8作为最新的目标检测框架,其高效的C2f模块和SPPF结构为频率检测提供了新思路。本文通过引入通道注意力机制和改进特征金字塔网络,构建了YOLOv8+CAA+HSFPN模型,显著提升了频率检测性能。 1.3. 频率检测任务特点分析 频率检测任务与一般目标检测存在显著差异: 1. 信号特性:频率信号通常呈现周期

By Ne0inhk
数据结构:⼆叉树(1)

数据结构:⼆叉树(1)

目录 前言  树部分知识: 一.树的概念和结构 二.树的一些相关术语和定义  三.树的实现结构(了解部分) 四、树的应用场景 二叉树部分知识讲解: 一.二叉树概念与结构 二.特殊二叉树类型 1.满二叉树 2.完全二叉树 3.性质补充 三、⼆叉树存储结构 顺序结构: 编辑应用: 链式结构: 四、堆的概念与结构 1.实现顺序结构⼆叉树: 2.堆的概念与结构 (重点) 3.堆的实现 五、堆的实现代码部分 1.堆的初始化:(本次实现选取大堆为例) 2.堆的销毁: 3.堆的插入数据 : 4.堆打印值 : 六、

By Ne0inhk
Flutter 三方库 libsignal 的鸿蒙化适配指南 - 实现 Signal 协议加密通信、双大鼠(Double Ratchet)算法与前向安全性保障

Flutter 三方库 libsignal 的鸿蒙化适配指南 - 实现 Signal 协议加密通信、双大鼠(Double Ratchet)算法与前向安全性保障

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 libsignal 的鸿蒙化适配指南 - 实现 Signal 协议加密通信、双大鼠(Double Ratchet)算法与前向安全性保障 前言 在 Flutter for OpenHarmony 的高度安全通信领域,Signal 协议是目前全球公认的即时通讯加密标准。libsignal 是 Signal 协议的核心 Dart 实现。它能够为鸿蒙应用提供从身份认证到会话加密的全套解决方案,确保每一个字节的通信都具备前向安全性(Forward Secrecy)。本文将深入解析如何在鸿蒙端利用该库构建极致安全的加密通信能力。 一、原理解析 / 概念介绍 1.1 基础原理 Signal 协议的核心在于“双大鼠(Double Ratchet)”算法。它结合了 Diffie-Hellman

By Ne0inhk