9月9日前端找工作学习

每日份学习分成三部分,leetcode算法,前端八股,休息&&整理每日学院的校招信息。

算法我不是很会,一般都是先自己思考,写不出来就会看答案,然后看懂答案。我用的是JS写算法,也会贴上一些我觉得写的比较好的博主的写法,如有侵权联系我。

1. 算法

  1. 两数之和
  2. 两数相加
  3. 无重复字符的最长子串
  4. 寻找两个正序数组的中位数

1.1 两数之和

题目描述:给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。

思路:找一个元素x,并判断对应的target-x是否存在

解法1-暴力解法

遍历数组,得到和数组元素i相加等于target的数值y(y=target-num)。判断数组是否含有元素y,且元素下标不能等于num的下标。

// 暴力
var twoSum = function(nums, target) {
    for(let i=0;i<nums.length;i++){
        let x=target-nums[i]
        let index=nums.indexOf(x)
        if(index!==-1 && index!==i){
            return [index,i]
        }
    }
    return []
};

解法2--使用hash map

之前也没接触过hash map是什么,hash散列表是为了将计算机不连续的内存利用起来,这部分需要自己去了解。我就里就是记住了map是键值对形式,HashMap是键值唯一。

这里是一边将数据元素加入到HashMap中,一边判断HashMap是否存在让数组元素i相加等于target的数值x。就是把上面的方法换成了HashMap判断。因为

var twoSum = function(nums, target) {
    let map =new Map();
    for(let i=0;i<nums.length;i++){
        let x=target-nums[i];
        if(map.has(x)){
            return [map.get(x),i]
        }else{
            map.set(nums[i],i)
        }
    }
    return []
};

1.2 两数相加

题目描述:给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

思路:直接按照加法列竖式的思想计算,但注意还要记录进位。因为最后返回链表,返回的头结点,所以还需要一个变量记录头结点位置。

解法1-暴力解法

new ListNode创建新节点,每次都要创建新节点来保存每个位上相加的值

var addTwoNumbers = function(l1, l2) {
    // 定义一个新的节点,然后暴力循环解决
    // let newHead=new ListNode() 创建新结点
    // 进位数
    let plus=0
    // 结果
    let result = new ListNode();
    let head = result; //用来保存头结点
    while(l1 || l2){
        // 求和
        let sum = ((l1 && l1.val) || 0) + ((l2 && l2.val) || 0) + plus
        // 取整,直接使用 / 运算符得到的是小数
        plus = Math.floor(sum / 10)
        let value = sum % 10
        result.next=new ListNode(value)
        result=result.next
        l1=l1 && l1.next
        l2=l2 && l2.next
    }
    if(plus){
        result.next=new ListNode(plus)
    }
    return head.next
};

1.3 无重复字符的最长子串

题目描述:给定一个字符串 s ,请你找出其中不含有重复字符的 最长 子串的长度。

思路:使用滑动窗口

解法1-滑动窗口这也是力扣的官方解法

就是遍历字符串,将其放到新数组arr中,右边界一直移动,左边界不动。但当发现相同的元素之后,左边界的下标则改为这个第一次出现这个元素的位置,同时使用splice,删除这个元素前面的元素。记录每次数组arr的大小,并得到最大的。

var lengthOfLongestSubstring = function(s) {
    let arr = [], max = 0
    for(let i = 0; i < s.length; i++) {
        let index = arr.indexOf(s[i])
        if(index !== -1) {
            arr.splice(0, index+1);
        }
        arr.push(s.charAt(i))   // arr.push(s[i])
        max = Math.max(arr.length, max) 
    }
    return max
};

解法2-使用set集合

考虑到set集合每个元素只出现一次,我使用的就是set集合。依次把字符元素加入到set集合中,但出现重复的时候,就将set置空,记录每次set的长度,从而得到最长的长度。

// 用set集合来判断,左边界依次是0,1,2,,n,通过set集合找到右边界
var lengthOfLongestSubstring = function(s) {
    const set =new Set()
    const n= s.length;
    let ans=0
    let max=0
    let right =1
    for(let i=0;i<n;i++){
        set.add(s.charAt(i))
        for(let j=i+1;j<n;j++){
            if(set.has(s.charAt(j))){
                ans=set.size
                max=Math.max(max,ans)
                set.clear()
                break
            }
            set.add(s.charAt(j))
        }
        ans=set.size
        max=Math.max(max,ans)
    }
    return max
};

1.4 寻找正序数组的中位数

题目描述:给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。

算法的时间复杂度应该为 O(log (m+n)) 。

解法1-暴力解法

将两个数组合并,排序,然后取中位数

var findMedianSortedArrays = function(nums1, nums2) {
    // 合并数组
    let nums=nums1.concat(nums2)
    nums.sort((a,b)=>a-b)
    let len=nums.length
    if(len % 2 == 0){
    // 偶数
        return (nums[len/2]+nums[len/2-1])/2
    }else{
    // 奇数
        return nums[Math.floor(len/2)]
    }
};

解法2-双指针遍历

需要判断数组越界的情况

var findMedianSortedArrays = function(nums1, nums2) {
    let len1=nums1.length;
    let len2=nums2.length;
    let point1=0,point2=0;  // 数组下标
    let value1=0,value2=0;  // 数组下标对应的值
    let len=nums1.length+nums2.length
    for(let i=0;i<=Math.floor(len/2);i++){
        value1=value2
        if((point1 < len1) && (point2 >= len2 || nums1[point1] < nums2[point2])){
            value2=nums1[point1]
            point1++
        }else{
            value2=nums2[point2]
            point2++
        }
    }
    if(len%2==0){
        return (value1+value2)/2
    }else{
        return value2
    }
};

我看还有比较高级的解法,我就不深究了。

今日份算法总结

  1. HashMap
  2. Set
  3. 滑动窗口
// 1. HashMap
let map =new Map()
map.has(x)  // 返回 false,true
map.get(x)
map.set(x,index)



// 2. set集合
let set=new set()
set.has()
set.add()
set.clear
set.size

let arr = [1,2,2,2,2,"2",24,5,6];
//step1:数组转集合
let set = new Set(arr);//已经去掉重复值,当前不是数组,而集合  Set { 1, 2, '2', 24, 5, 6 }
//step2:集合转数组
arr = [...set];//[ 1, 2, '2', 24, 5, 6 ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值