9月11前端学习笔记

1. 算法--双指针

1.1 移动零

题目描述:给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。请注意 ,必须在不复制数组的情况下原地对数组进行操作。

解法1:删除0元素+尾部补0

遍历数组,当遇到0元素的时候,就把这个元素从数组中删除,并在数组的尾部补0。特别注意的是数组长度的变化,数组元素位置的变化,要i--,还要判断i===nums.length

参考:JavaScript 经典算法面试题 - 移动零_给定一个数组 nums,编程实现将数组中包含的所有 0 移动到数组的前面,同时保持非零-优快云博客

var moveZeroes = function(nums) {
    // 0 的个数
    let b = 0;
 	for (let i = 0; i < nums.length; i++) {
      if(i === nums.length-b){
          break;
      }
      if (nums[i] === 0) {
        nums.splice(i, 1);
        nums.push(0);
         b++;
         i--
      }
    }
};

解法2:非0数字左移,剩余置为0 + 双指针

双指针两次遍历。第一次遍历将所有的非0元素左移,并记录下0元素的个数,第二次遍历将数组后面的元素都置0。

var moveZeroes = function(nums) {
    // 非0元素 的个数,非0元素应该存放的位置
    let  b= 0;
    //第一次遍历,将所有的非零元素移到左边
 	for (let i = 0; i < nums.length; i++) {
       if(nums[i]!=0){
           nums[b]=nums[i];
           b++;
       }
    }  
    // 将b下标开始的元素置0
    for(let i=b ; i<nums.length; i++){
        nums[i]=0
    }  
};

解法3:一次遍历+双指针

一个指针用来寻找非0元素,一个指针用来指向当前非0元素应该存放的位置。

var moveZeroes = function(nums) {
    // 非0元素应该存放的位置
    let  b= 0;
    for(let i=0;i<nums.length;i++){
        if(nums[i]!=0){
            let temp=nums[b]
            nums[b]=nums[i]
            nums[i]=temp
            b++;
        }
    }
};


// 也可以这样,避免一些不必要的交换
var moveZeroes = function(nums) {
    // b记录非0元素应该存放的位置
    let  b= 0;
    for(let i=0;i<nums.length;i++){
        if(nums[i]!=0){
            // 这里加一个判断
            if(nums[b]===0){
                let temp=nums[b]
                nums[b]=nums[i]
                nums[i]=temp
            }
            b++;
        }
    }
};

1.2 盛最多水的容器

题目描述:给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。

解法1:暴力解法

双重循环,第一重循环是左边界,第二重循环是右边界。

解法2:双指针移动短的一边

关于这个算法,其实我不太理解。但看到了一段话:移动短的一边是因为:如果移动长的一边,宽已经由短的一边固定了,长度在不断缩减,所以以后的面积只会比现在小;如果移动短的一边,即使长度变短了,但是宽度和长度的乘积可能会变大;最后就是将最大值返回。

注意:要先计算max后再移动指针

var maxArea = function(height) {
    let leftPoint=0
    let rightPoint=height.length-1;
    let max=0
    // 短的一边的高度
    let minHeight=0
    while(leftPoint<rightPoint){    
        minHeight = Math.min(height[leftPoint], height[rightPoint]);
        max=Math.max(max,(rightPoint-leftPoint)*minHeight)
        
        // 移动高度短的指针
        if(height[leftPoint]>height[rightPoint]){        
            rightPoint--;
        }else{      
            leftPoint++;
        }
        
    }
    return max
};

1.3 三数之和

题目描述:给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。

解法1:暴力解法

三重循环

解法2:双指针

先将数组进行排序,然后遍历nums[i],使用双指针找,左边为i+1,右边为len-1,求三者的和sum=nums[i]+nums[left]+nums[right],如果和小于0则左指针右移,如果和大于0则右指针左移,直到两者相遇。注意:可能会有重复的,要去重。

var threeSum = function(nums) {
    nums.sort((a,b)=>a-b);
    let res=[];
    for(let i=0;i<nums.length;i++){
        if(nums[i]>0) break;
        if(nums[i]==nums[i-1]){
            continue;
        }

        let left=i+1,right=nums.length-1
        while(left<right){

            // 也可以把去重放在这里
            // if(nums[left]==nums[left+1]){
            //     left++
            //     continue
            // }
            // if(nums[right]==nums[right-1]){
            //     right--
            //     continue
            // }



            let sum=nums[left]+nums[right]+nums[i]
            if(sum>0){
                right--
            }else if(sum<0){
                left++
            }else{
                res.push([nums[i],nums[left],nums[right]]);
                left++
                right--
                // 但是还要去重,[-2,0,0,2,2]这个例子
                while(left<right && nums[left]==nums[left-1]) left++
                while(left<right && nums[right]==nums[right+1]) right--

            }
        }
    }
    return res
};

总结

  1. 注意splice和slice函数的区别,一个是删除数组元素,插入数组元素,一个是截取数组

2. 前端八股

前端充电宝公众号

1. MVVM、MVC、MVP的区别

MVC、MVP 和 MVVM 是三种常见的软件架构设计模式。

MVC:M是数据层,负责和数据库进行交互,存取和操作数据;存储数据以及对数据的操作

            V是视图,负责用户界面呈现,仅显示从Model获取的数据。

            C是控制器,负责响应用户的操作。负责管理View到Model。

            M和V之间是观察者模式,当Model变化时,通知View去更新。当用户与页面View产生交互的时候,通过调用 Model 层,来完成对 Model 的修改,然后 Model 层再去通知 View 层更新。

View-->Controller-->Model--->View

MVP: P是中介者,可以从Model获取数据并更新View

MVVM: M是数据模型,数据和业务逻辑都在Model层中定义

             V是视图,负责展示页面

             VM是负责监听Model中数据的改变并且控制视图的更新,处理用户交互操作通过View来更新Model                                                       

 

 面试鸭公众号

1. 为什么Vue中的data属性是函数而不是对象

2. Vue的template标签有什么作用

3. 心得

今天做了一家公司的笔试,让我觉得,以刷力扣为重点是本末倒置,应该主要是要背前端八股,背自己的项目经验 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值