首页 > 其他分享 >[刷题技巧] LeetCode238. 除自身以外数组的乘积

[刷题技巧] LeetCode238. 除自身以外数组的乘积

时间:2024-01-14 17:45:54浏览次数:25  
标签:乘积 nums int res LeetCode238 数组 rightProduct 刷题

题目描述

思路:前缀/后缀乘积数组

构造除自身以外数组的左边前缀乘积
构造除自身以外数组的右边后缀乘积
然后对应位置相乘

方法一:

class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n = nums.length;
        // 前缀乘积数组: leftProduct[i]表示索引i左侧所有元素的乘积
        int[] leftProduct = new int[n];
        leftProduct[0] = 1;
        for (int i = 1; i < n; i ++) {
            leftProduct[i] = leftProduct[i - 1] * nums[i - 1];
        }
        // 后缀乘积数组:rightProduct[i]表示索引i右侧所有元素的乘积
        int[] rightProduct = new int[n];
        rightProduct[n - 1] = 1;
        for (int i = n - 2; i >= 0; i --) {
            rightProduct[i] = rightProduct[i + 1] * nums[i + 1];
        }
        // 对应位置相乘
        int[] res = new int[n];
        for (int i = 0; i < n; i ++) {
            res[i] = leftProduct[i] * rightProduct[i];
        }
        return res;
    }
}

时间复杂度:O(n)
额外空间复杂度:O(n)

方法二:优化方法一

class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n = nums.length;
        int[] res = new int[n];
        res[0] = 1;
        // res[i]表示索引i左侧所有元素的乘积
        for (int i = 1; i < n; i ++) {
            res[i] = res[i - 1] * nums[i - 1];
        }
        // 每个元素的右边所有元素的乘积存储在一个变量中
        int rightProduct = 1;
        for (int i = n - 1; i >= 0; i --) {
            // 对于索引i左边的乘积为res[i],右边的乘积为rightProduct
            res[i] = res[i] * rightProduct;
            // 更新右边乘积
            rightProduct = rightProduct * nums[i];
        }
        return res;
    }
}

在方法一的基础上进行优化:

  • 将res用于记录left数组
  • 然后用一个变量维护right数组

时间复杂度:O(n)
额外空间复杂度:O(1)

标签:乘积,nums,int,res,LeetCode238,数组,rightProduct,刷题
From: https://www.cnblogs.com/keyongkang/p/17963948

相关文章

  • [刷题技巧] 前缀和相关知识点汇总
    一、前缀和的作用前缀和技巧适用于快速、频繁地计算一个索引区间内的元素之和。二、前缀和的思路将原始数组进行预处理,将来需要查询数据的时候,只需要查询预处理的前缀和数组的某些值即可。前缀和的求解是【动态规划】。三、前缀和的定义四、前缀和数组的构造//int[]nums......
  • [刷题班] LeetCode1480. 一维数组的动态和
    题目描述思路:前缀和前缀和数组(prefixSum)的构造方法一:classSolution{publicint[]runningSum(int[]nums){int[]preSum=newint[nums.length];preSum[0]=nums[0];for(inti=1;i<nums.length;i++){preSum[i]......
  • [刷题班] LeetCode125. 验证回文串
    题目描述思路:左右指针只考虑数字和字母字母的话需要全部转化为小写然后使用左右指针判断是否是回文串方法一:classSolution{publicbooleanisPalindrome(Strings){List<Character>list=newArrayList<>();for(charc:s.toCharArray()){......
  • [刷题班] LeetCode11. 盛最多水的容器
    题目描述思路:左右指针方法一:暴力,超出时间限制模拟所有情况,记录最大的体积值。体积=Math.min(height[i],height[j])*(j-i)classSolution{publicintmaxArea(int[]height){intres=Integer.MIN_VALUE;for(inti=0;i<height.leng......
  • [刷题班] LeetCode27. 移除元素
    题目描述思路:快慢指针slow指针:其前面都是数值不等于val的元素。fast指针:用于遍历。方法一:classSolution{publicintremoveElement(int[]nums,intval){intslow=0,fast=0;for(;fast<nums.length;fast++){if(nums[fas......
  • [刷题班] LeetCode344. 反转字符串
    题目描述思路:左右指针方法一:classSolution{publicvoidreverseString(char[]s){intleft=0,right=s.length-1;while(left<right){chartemp=s[left];s[left]=s[right];s[right]=temp;......
  • [刷题班] LeetCode80. 删除有序数组中的重复项II
    题目描述思路:快慢指针slow指针指向已经处理元素的下一个位置因为数组有序,如果nums[fast]==nums[slow-2],那么nums[fast]肯定等于nums[slow-1],那么此时这个数就出现了三次。此时slow保持不变,fast继续遍历。关键:nums[fast]!=nums[slow-2]方法一:classSolution{......
  • [刷题班] LeetCode26. 删除有序数组中的重复项
    题目描述思路:快慢指针slow指针:指向已经处理的区域(没有重复元素)的最后一个位置fast指针:指向当前正在处理的元素方法一:classSolution{publicintremoveDuplicates(int[]nums){intslow=0,fast=0;for(;fast<nums.length;fast++){......
  • 刷题笔记——队列(C++)
    1696.跳跃游戏VI-力扣(LeetCode)给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。一开始你在下标 0 处。每一步,你最多可以往前跳 k 步,但你不能跳出数组的边界。也就是说,你可以从下标 i 跳到 [i+1,min(n-1,i+k)] 包含 两个端点的任意位置。你的目标是......
  • 刷题笔记——栈(C++)
    LCR148.验证图书取出顺序-力扣(LeetCode)现在图书馆有一堆图书需要放入书架,并且图书馆的书架是一种特殊的数据结构,只能按照 一定 的顺序 放入 和 拿取 书籍。给定一个表示图书放入顺序的整数序列 putIn,请判断序列 takeOut 是否为按照正确的顺序拿取书籍的操作序列。你可......