leetcode238-除自身以外数组的乘积

原题

给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。

示例:

输入: [1,2,3,4] 输出: [24,12,8,6]

提示: 题目数据保证数组之中任意元素的全部前缀元素和后缀(甚至是整个数组)的乘积都在 32 位整数范围内。

说明:不要使用除法,且在 O(n) 时间复杂度内完成此题。

进阶:
你可以在常数空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组不被视为额外空间。)

解法

思想

顺序相反的两次遍历

代码

func productExceptSelf(nums []int) []int {
    lsum := make([]int, len(nums))
    rsum := make([]int, len(nums))
    ans := make([]int, len(nums))
    for index := 0; index < len(nums); index++{
        if index == 0{
            lsum[index] = 1
        } else {
            lsum[index] = lsum[index-1] * nums[index-1]
        }
    }
    for index := len(nums) - 1; index >= 0; index--{
        if index == len(nums) - 1{
            rsum[index] = 1
        } else {
            rsum[index] = rsum[index+1] * nums[index+1]
        }
    }
    for index := 0; index < len(nums); index++{
        ans[index] = lsum[index] * rsum[index]
    }
    return ans
}

优化后:(减少空间复杂度,用ans代替lsum,用临时变量代替rsum)

func productExceptSelf(nums []int) []int {
    length := len(nums)
    answer := make([]int, length)

    // answer[i] 表示索引 i 左侧所有元素的乘积
    // 因为索引为 '0' 的元素左侧没有元素, 所以 answer[0] = 1
    answer[0] = 1
    for i := 1; i < length; i++ {
        answer[i] = nums[i-1] * answer[i-1]
    }

    // R 为右侧所有元素的乘积
    // 刚开始右边没有元素,所以 R = 1
    R := 1
    for i := length - 1; i >= 0; i-- {
        // 对于索引 i,左边的乘积为 answer[i],右边的乘积为 R
        answer[i] = answer[i] * R
        // R 需要包含右边所有的乘积,所以计算下一个结果时需要将当前值乘到 R 上
        R *= nums[i]
    }
    return answer
}

java:

class Solution {
    public int[] productExceptSelf(int[] nums) {
        int[] ans = new int[nums.length];
        ans[0] = 1;
        for(int i = 1;i<nums.length;i++){
            ans[i] = ans[i-1]*nums[i-1];
        }
        int prev = nums[nums.length-1];
        for(int i = nums.length-2;i>=0;i--){
            ans[i] = prev*ans[i];
            prev = prev*nums[i];
        }
        return ans;
    }
}

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/leetcode238-%e9%99%a4%e8%87%aa%e8%ba%ab%e4%bb%a5%e5%a4%96%e6%95%b0%e7%bb%84%e7%9a%84%e4%b9%98%e7%a7%af/

(0)
彭晨涛彭晨涛管理者
上一篇 2020年6月3日
下一篇 2020年6月5日

相关推荐

  • 剑指offer35-复杂链表的复制

    原题(来源Leetcode) 请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random …

    2020年6月13日
    0110
  • leetcode88-合并两个有序数组

    原题 给定两个有序整数数组 nums1 和 nums2 ,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。 说明: 初始化 nums1 和 nums2 的…

    算法 2020年2月23日
    0120
  • leetcode1431-拥有最多糖果的孩子(儿童节快乐!)

    原题 给你一个数组 candies 和一个整数 extraCandies ,其中 candies[i] 代表第 i 个孩子拥有的糖果数目。 对每一个孩子,检查是否存在一种方案,将额…

    算法 2020年6月1日
    0320
  • leetcode224-基本计算器

    原题 实现一个基本的计算器来计算一个简单的字符串表达式的值。 字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格 。 示例1: 输入: "1 + 1…

    算法 2020年1月26日
    0160
  • leetcode12-整数转罗马数字

    原题 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2…

    算法 2020年2月29日
    070
  • leetcode86-分隔链表

    原题 给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。 你应当保留两个分区中每个节点的初始相对位置。 示例: 输入: head…

    算法 2020年4月27日
    0160
  • 剑指offer47-礼物的最大价值

    原题(来源Leetcode) 在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一…

    算法 2020年6月12日
    090
  • leetcode41-缺失的第一个正数

    原题 给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。 示例 1: 输入: [1,2,0] 输出: 3 示例 2: 输入: [3,4,-1,1] 输出: 2 示例 3…

    算法 2020年5月11日
    0130
  • 海量数据-两种方法解决top k问题

    假如提供一百万个数据(甚至更大)的无序数组,如何从中获取最大的k个元素? 最容易想到的是先降序排序然后获取前k个元素,那假设我们用最常用的O(nlogn)级别的排序算法,要获取to…

    2020年4月4日
    0230
  • leetcode141-环形链表

    原题 给定一个链表,判断链表中是否有环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没…

    2019年12月14日
    0100

发表回复

登录后才能评论