每日题解:LeetCode 238. 除自身以外数组的乘积

题目地址
个人博客地址

题目描述

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

示例:

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

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

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

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

解法

JAVA

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

解题思路

  • 左右指针
    刚开始的想法,使用左右指针解法,从左边遍历乘积left到K,然后从数组的右边的遍历积right到K,然后左右的乘积left*right作为K的,即[k]=left*right
  • 利用数组
    假设我要求K+1的值,只需要将之前的left*K* (right(K+2))(right(K+1))是K+1下标右边的乘积,先暂时不计算这个值,我们先考虑K+1的左边,这样就没必要每次从左往右,从那就从左往右遍历一遍是数组,k+1的下标记录从0到K的乘积就好了。
 int len = nums.length;
int[] left = new int[len];

由于K+1的位置记录到K的乘积,所以需要一个变量错开

 int k = 1;
 //由于下标为0的左边的乘积没有,我们记录为1
for (int i = 0; i < len; i++) {
//先赋值,比如0下标的就记录为1
left[i]= k;
//然后乘积当前的值,赋值给i+1
k*=nums[i];
}

此时left[]数组记录了从左到右每个下标的乘积,我们以[1,2,3,4]为例,从此时left[]的值为[1,1,2,6]
然后我们计算从右到左的乘积,
下标3时,1*6
下标2时,4*2
下标1时,34*1
下标0时,3
4*2*1
红色标记为left的下标的值,此时,i的位置的答案(i+1)*(i+2)...*(len)*left[i]
那么只要从右往左进行遍历,然后变量记录i位置右边的乘积,然后和left[i]`相乘

k = 1;
for (int i = len - 1; i >= 0; i--) {
left[i]*=k;
k*=nums[i];
}

感觉今天的题解有点水的感觉,那我额外补充一点,在源码上的体验吧!!
最近一直在看JUC这块代码,觉得Doug Lea大佬真的厉害,下面贴出一个关于for循环的源码
在这里插入图片描述
这段代码来自ConcurrentHashMap的putVal,这里使用了for循环,在自旋的同时,还能获取到最新的table的值,非常的巧妙!!给大佬跪了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]:这段代码是一个解决LeetCode上某个题目的C++实现,具体是一个双指针的解法。该题目是计算一个数组中的积水量。代码中使用了两个指针分别指向数组的左右边界,然后通过比较左右指针所指向的元素的大小,来确定当前位置的积水量。具体的计算方法是,如果左指针所指向的元素小于右指针所指向的元素,则对左指针的左边进行操作,如果左指针所指向的元素大于等于右指针所指向的元素,则对右指针的右边进行操作。在每一次操作中,都会更新左边的最大值和右边的最大值,并计算当前位置的积水量。最后返回总的积水量。\[1\] 引用\[2\]:这段代码是另一个解决LeetCode上某个题目的C++实现,具体是一个深度优先搜索的解法。该题目是计算一个二维网格中从起点到终点的可行路径数量。代码中使用了递归的方式进行深度优先搜索,从起点开始,每次向下或向右移动一步,直到到达终点。在每一步移动中,会判断当前位置是否有障碍物,如果有障碍物则返回0,如果到达终点则返回1,否则继续递归搜索下一步的位置。最后返回总的可行路径数量。\[2\] 引用\[3\]:这段代码是另一个解决LeetCode上某个题目的C++实现,具体是一个动态规划的解法。该题目是计算一个数组中的积水量。代码中使用了动态规划的思想,通过遍历数组中的每个元素,分别计算该元素左边和右边的最大值,并计算当前位置的积水量。最后返回总的积水量。\[3\] 综上所述,这三段代码分别是解决LeetCode上不同题目的C++实现,分别使用了双指针、深度优先搜索和动态规划的方法来解决问题。 #### 引用[.reference_title] - *1* *3* [Leetcode 热题100 42.接雨水(C++ 多种解法,错过可惜)](https://blog.csdn.net/qq_51933234/article/details/124637883)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [[C++]Leetcode 不同路径 || 解题思路及详解](https://blog.csdn.net/weixin_62712365/article/details/123951736)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值