不管是初入职场的新人亦或饱经沧桑的老手,在技术生涯中无疑都会面临最大的挑战——面试,挑战成功就是百尺竿头更上一步,挑战失败估计免不了被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)。
以上仅为参考,解题思路万千并非唯一,请结合具体案例编写测试用例验证正确性。同时也请进一步思考是否有更优的算法。