不管是初入职场的新人亦或饱经沧桑的老手,在技术生涯中无疑都会面临最大的挑战——面试,挑战成功就是百尺竿头更上一步,挑战失败估计免不了被diss了。实际上国外许多企业以及当前国内的大厂,在面试环节都会有一到两轮的Algorithm over CoderPad或 Algorithm On Whiteboard环节,对于终日忙于编写业务代码或者由于996没时间温习基础算法的同学,毫无疑问挑战是巨大的。因此本系列文章的目的是剖析常见的Leetcode算法题并提供一些经典的解题套路。机会总是留给有准备的人,希望每个技术开发者的技术之路都能走得更好。

通过LeetCode练习算法题,对于面试成功至关重要!当阅读并练习时,建议把它当做真正的编码轮面试,思考算法的原理,分析其时间和空间复杂度并作为注释,并且手动编写测试用例来验证正确性。

我们会先从简单开始的算法开始,在数组和字符串上混合一些简单和中等的问题。由于数组和字符串是面试中最常见的问题类型,因此熟悉它们有益于建立坚实的基础知识,从而更好地处理复杂问题。

问题238:ProductExceptSelf有效括号问题

描述:给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积,并且在O(n)时间复杂度内完成。

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

思路分析:

1.叠积法

从问题描述分析,需要求解的新数组中每个元素为除该元素以外的各个元素乘积。最简单的做法可以使用暴力破解,但问题要求在O(n)的时间复杂度内完成,因此调整思路在一层循环中解决问题。在从左至右遍历每个元素时,将除当前元素外的左积写入对应数组元素;当从右往左遍历元素时,将除当前元素外的右积*左积写入对应数组元素。

代码实现:

public static int[]productExceptSelf(int[] nums) {
 int[] p = new int[nums.length];
 int k = 1;
 for (int i = 0; i < nums.length; i++) {
   // p[i]为除当前nums[i]以外的左元素积
   p[i] = k;
   k = k * nums[i];
  }
  k= 1;
 for (int j = nums.length - 1; j >= 0; j--) {
   // p[j]为除当前nums[j]以外的左右元素乘积
   p[j] = p[j] * k;
   k = k * nums[j];
  }
 return p;
}

复杂度分析:时间复杂度为O(n),因为需要双向按序遍历给定的数组。空间复杂度为O(n)。

以上仅为参考,解题思路万千并非唯一,请结合具体案例编写测试用例验证正确性。同时也请进一步思考是否有更优的算法。