最求极致=》我是如何把easy级别的算法题做成hard级别的构建乘积数组=》必学算法思维/技巧

Posted 勇敢*牛牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最求极致=》我是如何把easy级别的算法题做成hard级别的构建乘积数组=》必学算法思维/技巧相关的知识,希望对你有一定的参考价值。

【最求极致】=》我是如何把easy级别的算法题做成hard级别的

【构建乘积数组】=》必学算法思维/技巧

我们平时在刷题的时候,我觉得大致可分为以下几类题


1、这道题的暴力解法很简单,几乎人人都会做,但最优解却很难

2、如果你懂某些算法思想,这道题很简单,如果不懂,那么这道题顿时很难,例如有些需要dp来处理的。

3、这种题型没做过,没啥思路,但接触过好几道之后,便会觉得异常简单,例如不能使用加减乘除运算符来完成加法运算。

4、最后一种是属于真正的难题,思路难想 ,就算知道了思想,编码也很难,因为临界点之类的特别多,逻辑特别复杂。


而我今天要强调的就是第一类题 ,我这里给的建议是,我们要追求极致,并且我今天会给出1道例题,大家也可以借鉴参考。 🎆====这是一条分割线====🎆 “我在牛客网刷题的时候,发现有些题的解法,如果你是采用暴力的话,是异常简单的,但是每次遇到这种题,我都不会轻易马上写代码,而是苦思一会,看看有没有优雅的解法。不过我去看很多通过的代码,发现大部分人的解法都是很普通,几乎算是暴力法,可能那些人看到这道题的时候心想:我去,又秒杀一道题了,三分钟撸好了代码,一次就ac了这道题,心里满满的快感,马上接着下一题走起。

但是,这种做法我是不支持的,因为这道题如果你草草了事,那么你没有任何优势,因为你这种解法别人也会;而且,做完这道题,你可能没有任何收获,估计只收获了快感。也就是说,做完这道题,你并没有收获到这道题最核心的解法

所以,我觉得,对于这种题,我们一定要追求极致,不能“得过且过”。把这道题的精华吸收。

题目1: 构建乘积数组

题目描述:
给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]A[1]…A[i-1]A[i+1]…A[n-1]。不能使用除法。

这道题简单吗?就算不能使用除法,也是挺简单的,每次算 B[i],都全部遍历一下数组,两个 for 循环就搞定了,时间复杂度是 O(n^2)。

但是,我敢保证,这种做法95%的人都会做,没有任何优势。所以我们想想是否有更加优雅的解法,有人说,想不出来怎么办?

很简单,想不出来就看看别人怎么做,百度搜索 or 讨论区看答案。看别人的解法,一点也不丢人。

所以对于这道题,更好的解法应该是这样的:

  • 对于这道题,要求对于一个数组,返回除了该位之外的所有的累加乘积。
  • 对于这种需要遍历整个数组并返回除了自己之外的计算结果的题目,我们可以利用从前往后、从后往前的策略,来对整个数组实现遍历并计算乘积的功能。
  • 在从前往后遍历时,我们利用一个变量记录从开始到当前位置的累加和。
  • 从后往前也是一样,记录乘积。

————————————————

1、先算出 B[i] = A[0] * …A[i-1]。”
2、接着算 B[i] = A[i+1]…A[n-1] * Bi

代码如下

import java.util.ArrayList;
public class Solution 
    public int[] multiply(int[] A) 
        /*这道题的中心思想是将返回的数据列成一个矩阵,每一个矩阵的行向量都是一个从a(0)到a(n-1)
          ,然后这个对角线都是1.那么此时B0的值就是A0为一,剩下的行向量相乘。
        */
        int length = A.length;
        int[] B = new int[length];
        B[0] = 1;
        for(int i = 1; i < length; i ++)
            B[i] = B[i - 1] * A[i - 1];
        
        int temp = 1;
        for(int j = length - 2; j >= 0; j --)
            temp *= A[j + 1];//temp始终会记录值,每次只需要加上这行上三角没有乘进来的数就可以了。
            B[j] *= temp;
        
        return B;
    

时间复杂度是 O(n)。有人可能会问,那我怎么知道这个解法是否就为最优解了呢?我觉得这个可以自己判断,加上多看一些点赞高的人的解法,如果时间复杂度、空间复杂度都和你差不多,那么几乎就可以认为是最优解了。就算实际上不是,而大佬们也都这样解,那么也可以姑且认为是最优解了。最重要的是,比你最开始想的解法好多了就行了。”

以上是关于最求极致=》我是如何把easy级别的算法题做成hard级别的构建乘积数组=》必学算法思维/技巧的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode算法题-N-ary Tree Level Order Traversal(Java实现)

算法LeetCode算法题-Maximum Subarray

太震撼了!我把七大JS排序算法做成了可视化!!

LeetCode算法题-Reverse Bits(Java实现)

太震撼了!我把七大JS排序算法做成了可视化!!!太好玩了!

算法LeetCode算法题-Count And Say