【剑斩OFFER】算法的暴力美学——除自身以外数组的乘积

一、题目描述

二、算法原理

我们如果暴力查找时复杂度是非常高的,所以这里我们弄两个数组,一个求的是前缀的积,另外一个求的是后缀的积。

求前缀的时候是从左往右求,而后缀是从右往左求。

前缀特殊情况:当 i = 0 时,i - 1 是会越界的,所以这里当 i = 0 时,直接让他等于原数组的第一个数字就行。

后缀特殊情况:当 i = 数组长度 - 1,i + 1 是会越界的,所以当 i = 数组长度 - 1 时,直接等于原数组的最后一个数。

上面图片的 left 就是前缀求积,而 right 就是求后缀的积。

那么怎么使用这俩个数组来解决这道题目呢?

当 i = 2 ,这里就等于:2 * 4 = 8;

所以:这里也就得出个公式:ret[ i ] = left[ i - 1] * right[ i + 1]

这个公式有两个特殊情况:

当 i = 0,i - 1 会越界,所以当 i = 0,直接让他等于:right[ i + 1]

当 i = 数组的长度 - 1,i + 1会越界,所以直接让他等于:left[ i - 1]

三、代码实现

cpp 复制代码
class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        vector<int> left(nums.size());
        vector<int> right(nums.size());
        int len = nums.size();
        for(int i = 0; i < len; i++)
        {
            if(i == 0) left[i] = nums[i];
            else left[i] = left[ i - 1] * nums[i];
        }
        for(int j = len - 1; j >= 0; j--)
        {
            if(j == len - 1) right[j] = nums[j];
            else right[j] = right[j + 1] * nums[j];
        }

        vector<int> ret(len);

        for(int k = 0; k < len; k ++)
        {
            if(k == 0) ret[k] = right[k + 1];
            else if(k == len - 1) ret[k] = left[k - 1];
            else ret[k] = left[k - 1] * right[k + 1];
        }
        return ret;
    }
};
相关推荐
cpp_2501几秒前
P8377 [PFOI Round1] 暴龙的火锅
数据结构·c++·算法·题解·洛谷
uesowys9 分钟前
Apache Spark算法开发指导-Factorization machines classifier
人工智能·算法
TracyCoder12328 分钟前
LeetCode Hot100(26/100)——24. 两两交换链表中的节点
leetcode·链表
季明洵36 分钟前
C语言实现单链表
c语言·开发语言·数据结构·算法·链表
shandianchengzi40 分钟前
【小白向】错位排列|图文解释公考常见题目错位排列的递推式Dn=(n-1)(Dn-2+Dn-1)推导方式
笔记·算法·公考·递推·排列·考公
I_LPL40 分钟前
day26 代码随想录算法训练营 回溯专题5
算法·回溯·hot100·求职面试·n皇后·解数独
Yeats_Liao42 分钟前
评估体系构建:基于自动化指标与人工打分的双重验证
运维·人工智能·深度学习·算法·机器学习·自动化
cpp_25011 小时前
P9586 「MXOI Round 2」游戏
数据结构·c++·算法·题解·洛谷
浅念-1 小时前
C语言编译与链接全流程:从源码到可执行程序的幕后之旅
c语言·开发语言·数据结构·经验分享·笔记·学习·算法
有时间要学习1 小时前
面试150——第五周
算法·深度优先