[算法题] Leetcode 152:乘积最大连续子序列(JavaScript)

写在前面

昨晚做某厂前端笔试题,编程有一道是leetcode 152的乘积最大连续子序列,因为算法掌握特别不扎实,所以事后一搜索,这题用的是动态规划方法解。事实上,到现在也没有太懂动态规划究竟是什么思想,但基本上理解了这题的思路。网络上大部分前辈的代码都是基于Java or C++,两年前C++我也可QAQ,但两年的硕士生活让我忘记了计算机专业的所有的基本。由于在准备前端,最近恶补了一下JavaScript,目前是我写的最顺手的语言。
前言说的有点多,下面切正片。

题目描述:

找出一个序列中乘积最大的连续子序列(该序列至少包含一个数)。
例如, 给定序列 [2,3,-2,4],其中乘积最大的子序列为 [2,3] 其乘积为 6

我的注: 这个示例输入输出让荒唐的我把这道题荒唐地理解成了只包含两元素的最大值,于是有了下面这段荒唐的代码(可以不用看

function maxProduct(nums) {
	let mul = [],
		result = null;
	if(nums.length === 1){
        return nums[0];
    };
	
	for(let i = 0;i < nums.length - 1; i++) {
		mul.push(Math.max(nums[i] * nums[i+1]));
	};
	result = Math.max.apply(null, mul);
	return result;
};

傻得天真。
当看到一个示例为 输入[-2, 3, -4],输出24,我的心里有一百万个?。后知后觉。
所以不管是什么考试,希望能注意 认真读题
二切正片。

解答

因为看懂了前辈们的思路,所以没有尝试任何暴力解决方法。
思路 - 动态规划。

每有一个新的数字加入,最大值为当前最大值 x 新数,或当前最小值(负数) x 新数(负数),否则为当前值(设置为当前值,是为了保证求得最大值的子序列连续性,若本次加入新数取得的值不是当前的最大值,则可看作是开始新一段子序列的计算)。

/*
 * @param {number[]} nums
 * @return {number}
 */
function maxProduct(nums) {
    if (typeof nums[0] === 'undefined' || nums.length === 0) {
        return 0;
    };
    let max = nums[0],
        min = nums[0],
        result = nums[0];
    for (let i = 1; i < nums.length; i++) {
        let temp = max;
        max = Math.max(Math.max(max * nums[i], min * nums[i]), nums[i]);
        min = Math.min(Math.min(temp * nums[i], min * nums[i]), nums[i]);
        if(max > result) {
            result = max;
        };
    };
    return result;
};

第一次写博客,核心部分借鉴的成分比较多,希望慢慢的有更多自己的东西。
以上。



参考博客:https://blog.csdn.net/weixin_41876155/article/details/80052401(谢谢这位前辈)

2019/09/05/ 14:11:08

你可能感兴趣的:([算法题] Leetcode 152:乘积最大连续子序列(JavaScript))