LeetCode 数组两题//11.13Morning

本文介绍了两种JavaScript解题策略,包括暴力法和双指针法,分别应用于求解盛最多水的容器的最大面积和最大子序和问题。暴力法通过双重循环实现,但效率较低,易造成内存溢出;双指针法则更优,时间复杂度为O(n)。在最大子序和问题中,通过单层循环不断更新最大值和当前和,实现了更高效的解决方案。
摘要由CSDN通过智能技术生成

JS语言

1.

11

盛最多水的容器  

172464.4%中等 

法一:暴力法 双重for循环

时间复杂度 O(n²) ,前n项和

一开始想把所有的值添加到空数组中,最后return Math.max.apply(null,arr),但超过内存限制

设置null的原因:表示把null传给函数中的this。因为max是不用this的,这里方便起见就传个null,起占位作用。

但其实可以全局声明变量res=0,然后比较新值和res大小,不停更新变量即可,不用先push到数组里这么麻烦。更新的过程可以if,也可以三元表达式。

回头看发现太麻烦了,下面代码也别扭

/**
 * @param {number[]} height
 * @return {number}
 */
var maxArea = function(height) {
    // let arr = [];
    let res = 0;
    for(let i=0; i < height.length - 1; i++) {
        for(let j =i+1; j < height.length; j++) {
            // arr.push((j-i)*Math.min(height[i],height[j]));
            // a = (j-i)*Math.min(height[i],height[j]);
            // if(res < a){
            //     res = a;
            // }
            res = res<(j-i)*Math.min(height[i],height[j])? (j-i)*Math.min(height[i],height[j]):res
        }
    }
    // return Math.max.apply(null,arr);
    return res;
};
// 内存溢出

法二:双指针(最优解)

不太好想

双指针移动距离总共为n,所以时间复杂度为O(n)

注意 i++ 这种后置递增运算符,是先返回原值,再自加1

/**
 * @param {number[]} height
 * @return {number}
 */
var maxArea = function(height) {
    let i = 0;
    let j = height.length-1;
    let max = 0;
    while (i<j) {
        max = Math.max(max,(j-i)*(height[i]<height[j]?height[i++]:height[j--]));
    }
    return max;
}

注意:

三元表达式外面加括号

三元表达式中i/j++被执行才会先返回i再自加1,否则仍是原来的i/j

 

2.

53

最大子序和  

191652.7%简单 

法一:同样是暴力法

双重for循环

/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function(nums) {
    let max = nums[0];
    for(let i = 0; i < nums.length; i++) {
        let sum = 0;
        for(let j = i; j < nums.length; j++) {
            sum += nums[j];
            // max = sum < max ? max:sum
            max = Math.max(max,sum)
        }
    }
    return max;
};

注意内层循环每次开始的时候都let sum重新为0,而max在最外层声明

第二点注意的是,最后用Math.max和三元表达式都可以对max更新

缺点:虽然能AC,但是时间复杂度太高:

法二:单层循环

此法是学习了别人的思路:

 

/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function(nums) {
    let max = nums[0];
    let sum = 0;
    for(let i = 0; i < nums.length; i++) {
        sum = Math.max(nums[i],nums[i]+sum);
        max = Math.max(sum,max)
    }
    return max;
};

这里的sum更新方式很特别,再理解一下。

第一次取 数组当前项 与数组当前项+之前项和(有的情况不是前所有项) 的最大值
第二次取 最大值 和 当前和 的最大值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值