【优选算法必刷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

Flutter for OpenHarmony:mockito 单元测试的替身演员,轻松模拟复杂依赖(测试驱动开发必备) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:mockito 单元测试的替身演员,轻松模拟复杂依赖(测试驱动开发必备) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 在软件开发中,单元测试(Unit Testing)是保证代码质量的基石。然而,在测试某个具体的业务逻辑(如 UserService)时,我们往往会遇到各种外部依赖,比如数据库查询、网络请求、设备传感器等。 如果直接调用真实的 Database 或 HttpClient,不仅测试速度慢,而且容易因为网络抖动或环境问题导致测试失败。此外,我们很难复现一些极端场景(如 500 服务器错误、数据库连接超时)。 Mockito 就是为了解决这个问题而生的。它允许我们创建对象的 Mock(替身),并精确控制这些替身的行为(Stubbing)和验证它们的交互(Verification)。 在 OpenHarmony 应用开发中,使用 mockito 可以让我们在开发机(Host)上就能快速验证大部分业务逻辑,通过后再部署到鸿蒙真机进行集成测试,

By Ne0inhk
Flutter for OpenHarmony:filesize 人类可读文件大小转换库(极简实用工具) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:filesize 人类可读文件大小转换库(极简实用工具) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 在应用开发中,我们经常需要显示文件大小: * 下载进度条: 15.4 MB / 102.0 MB * 缓存管理页面: Clean 234.5 KB * 系统存储详情: Available: 12.1 GB 如果直接显示字节数 12345678 Bytes,用户会一脸茫然。我们需要将字节转换成 KB, MB, GB 等单位,并保留适当的小数位。 虽然写一个除法函数很简单,但要处理好边缘情况(如 1024 vs 1000 进制,小数点保留,单位后缀 KiB vs KB),还是直接用现成的库来得稳妥。 filesize 就是这样一个极简的

By Ne0inhk
Docker配置镜像源 解决拉取镜像超时 ERROR: failed to solve xx: : failed to resolve source metadata for docker.io/li

Docker配置镜像源 解决拉取镜像超时 ERROR: failed to solve xx: : failed to resolve source metadata for docker.io/li

分析问题: 我在构建镜像时报错:ERROR: failed to solve: golang:1.21: failed to resolve source metadata for docker.io/library/golang:1.21: failed to do request: Head "https://registry-1.docker.io/v2/library/golang/manifests/1.21": dial tcp 202.160.128.205:443: i/o timeout 排查原因,是构建过程中拉取镜像时出现了超时问题。

By Ne0inhk
十五、中秋特别篇:深入理解 SELinux - 系统安全的“月饼”与“门禁”

十五、中秋特别篇:深入理解 SELinux - 系统安全的“月饼”与“门禁”

值此中秋佳节,皓月当空,阖家团圆。在享受美味月饼的同时,我们不妨来聊聊Linux 系统中那位默默守护“家宅平安”的忠诚卫士——SELinux。 SELinux (Security-Enhanced Linux) 是一个由美国国家安全局 (NSA)主导开发的强制访问控制 (MAC)安全子系统。它不再仅仅依赖“钥匙”,而是像一个一丝不苟的智能门禁系统。在这个系统里,每个人(进程) 和每个房间(文件、端口)都被贴上了独一无二的电子标签 (安全上下文)。门禁系统手握一本厚厚的“通行规则手册” (安全策略),严格规定了“谁”在什么时间可以进入“哪个房间”做什么事。 思维导图 一、SELinux 的核心概念与工作流程 想象一下中秋家宴,SELinux就像家里的管家,确保一切井然有序。 核心概念中秋家宴比喻描述示例主体家庭成员/客人发起动作的实体,通常是进程。httpd 进程 (想端菜的厨师)客体月饼/

By Ne0inhk