力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)

力扣 — 前端面试高频算法题总结(codeTop)


注意:

根据下图了解对应数据表示信息:

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第1张图片


文章目录

  • 力扣 --- 前端面试高频算法题总结(codeTop)
    • 1、[无重复字符的最长子串(42)](https://leetcode-cn.com/problems/longest-substring-without-repeating-characters)
    • 2、[合并两个有序数组(38)](https://leetcode-cn.com/problems/merge-sorted-array)
    • 3、[字符串相加(35)](https://leetcode-cn.com/problems/add-strings)
    • 4、[比较版本号(31)](https://leetcode-cn.com/problems/compare-version-numbers)
    • 5、[两数之和(31)](https://leetcode-cn.com/problems/two-sum)
  • 第二次更新
    • 6、[有效的括号(26)](https://leetcode-cn.com/problems/valid-parentheses)
    • 7、[爬楼梯(25)](https://leetcode-cn.com/problems/climbing-stairs)
    • 8、[全排列(25)](https://leetcode-cn.com/problems/permutations)
  • 第三次更新
    • 9、[最大子序和(25)](https://leetcode-cn.com/problems/maximum-subarray)
    • 10、[ 反转链表(22)](https://leetcode-cn.com/problems/reverse-linked-list)
    • 11、[路径总和(21)](https://leetcode-cn.com/problems/path-sum)
  • 第四次更新
    • 12、[二叉树的层序遍历(20)](https://leetcode-cn.com/problems/binary-tree-level-order-traversal)
    • 13、[数组中的第K个最大元素(19)](https://leetcode-cn.com/problems/kth-largest-element-in-an-array/)
    • 14、[ 三数之和(18)](https://leetcode-cn.com/problems/3sum)
  • 第五次更新
    • 15、[环形链表(18)](https://leetcode-cn.com/problems/linked-list-cycle)
    • 16、[补充题4. 手撕快速排序(18)](https://leetcode-cn.com/problems/sort-an-array)
    • 17、[ 求根节点到叶节点数字之和(18)](https://leetcode-cn.com/problems/sum-root-to-leaf-numbers/)
  • 第六次更新
    • 18、[最长回文子串(17)](https://leetcode-cn.com/problems/longest-palindromic-substring)
    • 19、[买卖股票的最佳时机(14)](https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock)
    • 20、[二分查找(14)](https://leetcode-cn.com/problems/binary-search)
  • 第七次更新
    • 21、[合并两个有序链表(12)](https://leetcode-cn.com/problems/merge-two-sorted-lists)
    • 22、[螺旋矩阵(12)](https://leetcode-cn.com/problems/spiral-matrix)
    • 23、[最长上升子序列(12)](https://leetcode-cn.com/problems/longest-increasing-subsequence)
  • 第八次更新
    • 24、[ 二叉树的中序遍历(12)](https://leetcode-cn.com/problems/binary-tree-inorder-traversal)
    • 25、[二叉树的最大深度(12)](https://leetcode-cn.com/problems/maximum-depth-of-binary-tree)
    • 26、[岛屿数量(11)](https://leetcode-cn.com/problems/number-of-islands)
  • 第九次更新
    • 27、[零钱兑换(11)](https://leetcode-cn.com/problems/coin-change)
    • 28、[剑指 Offer 22. 链表中倒数第k个节点(11)](https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof)
    • 29、[括号生成(10)](https://leetcode-cn.com/problems/generate-parentheses)
  • 第十次更新
    • 30、[最长重复子数组(9)](https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray)
    • 31、[二叉树的前序遍历(9)](https://leetcode-cn.com/problems/binary-tree-preorder-traversal)
    • 32、[合并区间(9)](https://leetcode-cn.com/problems/merge-intervals)


1、无重复字符的最长子串(42)

image-20220307085943830

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第2张图片

题解思路:动态规划
用一个空字符串,动态保存无重复的字符,并动态保存最大的无重复字符
当遇到重复的字符后,
从第一个重复的字符的下标往后一位切割并拼接上第二个重复的字符,例如 ‘abca’ ==> ‘bca’

// 用字符串保存结果
/*
	思路:
	用一个空字符串,动态保存无重复的字符,并动态保存最大的无重复字符
	当遇到重复的字符后,
	从第一个重复的字符的下标往后一位切割并拼接上第二个重复的字符,例如 'abca' ==> 'bca'
*/
var lengthOfLongestSubstring = function(s) {
    var str="" //存放无重复子串
    var size=0 //当前最长无重复子串的长度
    for(var i=0,len=s.length;i<len;i++){
        var index=str.indexOf(s[i])
        if(index==-1){
            str+=s[i]
            size=size<str.length?str.length:size
        }else{
            str=str.substr(index+1)+s[i]
        }
    }
    return size
};


//上题的用数组保存做法
var lengthOfLongestSubstring = function(s) {
    var str =''
    var res = []
    for (let i of s ){
        var index = str.indexOf(i)
        if(index < 0){
            str +=i
        }else{
            //  将重复前的字符放入数组中
            res.push(str)
            // 字符串切换到第一个重复后一位,例如 'abca' ==> 'bca'
            str = str.substr(index + 1) + i
        }
    }
    // 将没重复的放入数组
    res.push(str)
    // 将数组的字符从大到小降序排列,第一个就是最大的长度
    res.sort((a,b)=> b.length - a.length)
    return res[0].length
};

2、合并两个有序数组(38)

image-20220307092327713

题解思路:双指针
具题目了解两数组以递增排好序
应题目最终要求将结果保存在数组1中,所以将在数组1中进行后续操作
从数组1的最后开始循环判断将两数组中的最大的放入,并将对应的指针,及数组的长度推进
最后形成的数组1就是排好的两数组

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第3张图片

/*
	题解思路:双指针
	具题目了解两数组以递增排好序
	应题目最终要求将结果保存在数组1中,所以将在数组1中进行后续操作
	从数组1的最后开始循环判断将两数组中的最大的放入,并将对应的指针,及数组的长度推进
	最后形成的数组1就是排好的两数组
*/
var merge = function(nums1, m, nums2, n) {
    let len = nums1.length -1 // 对应下标都为数组的长度-1
    m--
    n--
    while(n>=0){
        //  在第二个数组推入完之前,都进行循环,将两数组中最大的放入最后
        if(nums1[m] > nums2[n]){
            nums1[len--] = nums1[m--]  
        }else{
            nums1[len--] = nums2[n--]
        }
    }
};

3、字符串相加(35)

image-20220307093546321

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第4张图片

题解思路:双指针
创建两个指针i,j分别为两数组的最后下标
将两数组的最后一位分别转为数值,随后进行相加,进位树保存给下一次相加
将所有结果的个位数全部放在一个数组里,最后拼接为字符串返回

/*
	题解思路:双指针
	创建两个指针i,j分别为两数组的最后下标
	将两数组的最后一位分别转为数值,随后进行相加,进位树保存给下一次相加
	将所有结果的个位数全部放在一个数组里,最后拼接为字符串返回
*/
var addStrings = function(num1, num2) {
    let i = num1.length - 1
    let j = num2.length - 1
    let carry = 0  // 进位数,即留到下一轮相加的数
    let res = [] // 存放相加结果的个位数
    while(i >= 0 || j >= 0 || carry !== 0) {
        //  将v1 , v2 转为数值,其中一个数加完 <0 后赋值对应值为0,防止出错
        const v1 = i >= 0 ? num1.charAt(i) - '0' : 0
        const v2 = j >= 0 ? num2.charAt(j) - '0' : 0
        let val = v1 + v2 + carry
        res.unshift(val % 10)  // 将相加后的个位数放进数组,用unshift从头往前放,因为是从后往前相加的
        carry = Math.floor(val / 10)  // 相加后的十位数,留在下一次作为进位数一起进行相加
        // 两个指针继续往前走
        i--
        j--
    }
    return res.join('')
};

4、比较版本号(31)

image-20220307094757662

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第5张图片

题解思路:spilt分割+数值转化

​ 使用字符串的split分割’.’,随后得到分割后的数组
​ 从两个数组中最大的长度进行循环,防止比较不完全
​ 逐个将分割后的数组提出来,将其转为数值后会忽略前导0,然后再进行比较,若相等则进行下次比较
​ 最后都相等的话,就返回0

/*
	题解思路:使用字符串的split分割'.',随后得到分割后的数组
	从两个数组中最大的长度进行循环,防止比较不完全
	逐个将分割后的数组提出来,将其转为数值后会忽略前导0,然后再进行比较,若相等则进行下次比较
	最后都相等的话,就返回0
*/
var compareVersion = function(version1, version2) {
    let arr1 = version1.split('.'); //  1.01  == > [1,01]
    let arr2 = version2.split('.');// 	1.001 == > [1,001]
    for(let i = 0; i <  Math.max(arr1.length,arr2.length) ; i++){
        let x1 = arr1[i] || 0  
        let x2 = arr2[i] || 0
        if(+x1 == +x2){  //  比较时 01 => 1 ,  001 => 1 转为数值自动将忽略前导0
            continue
        }else if(+x1 > +x2){
            return 1
        }else if(+x1 < +x2){
            return -1
        }
    }
    return 0
};

5、两数之和(31)

image-20220307095546641

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第6张图片

题解思路:使用map保存出现过的数
目标和 – 当前数 等于rest 若rest,在对象中保存过则说明两数相加等于目标和,最后返回两坐标即可
例如:[2,7,3] target = 9
第一次 rest = 9 - 2 = 7
并在map中保存出现的 2(nums[i])和对应的下标(i)
第二次中 rest = 9 - 7 = 2
在map中找到出现过的 2,说明两个之和等于target
最后用数组返回对应下标 [map.get(rest),i]
map.get(rest) 会返回2的下标,因为就是用它的下标值保存在map中
i 为当前数下标

/*
	题解思路:使用map保存出现过的数
	目标和 -- 当前数 等于rest  若rest,在对象中保存过则说明两数相加等于目标和,最后返回两坐标即可
	例如:[2,7,3] target = 9
	第一次 rest = 9 - 2 = 7
	并在map中保存出现的 2(nums[i])和对应的下标(i)
	第二次中 rest = 9 - 7 = 2
	在map中找到出现过的 2,说明两个之和等于target
	最后用数组返回对应下标 [map.get(rest),i] 
	map.get(rest) 会返回2的下标,因为就是用它的下标值保存在map中
	i  为当前数下标
*/
ar twoSum = function(nums, target) {
    let map = new Map()
    let len = nums.length
    for(let i =0 ;i<len ;i++){
        let rest = target - nums[i] 
        if(map.has(rest)){
            return [map.get(rest),i]
        }
        map.set(nums[i],i)
    }
};

第二次更新


6、有效的括号(26)

image-20220308105108958

image-20220308105118699

题解思路:利用栈结构先进后出,满足有效括号要求
创建一个对象,保存左括号对应的右括号值
遍历字符里出现的有效左括号,然会推入栈中
在遍历右括号时,从栈中从栈尾依次取出,若取出的不等于当前的右括号则不是有效括号
例如:当输入 “([)]”,
栈中保存 [ )] ]
当遍历到 ‘)’ 时,从栈中取出的为 ‘]’ ,不相等,则不是有效括号

注意:
最后返回判断的是栈内是否为空数组,
因为可能有输入 ‘(’ 然后栈内还有 ‘)’

/*
	题解思路:利用栈结构先进后出,满足有效括号要求
	创建一个对象,保存左括号对应的右括号值
	遍历字符里出现的有效左括号,然会推入栈中
	在遍历右括号时,从栈中从栈尾依次取出,若取出的不等于当前的右括号则不是有效括号
	例如:当输入  "([)]",
	栈中保存 [ )] ]
	当遍历到 ')' 时,从栈中取出的为 ']' ,不相等,则不是有效括号
	
	注意:
	最后返回判断的是栈内是否为空数组,
	因为可能有输入 '(' 然后栈内还有 ')' 
*/

var isValid = function(s) {
    if(!s) return true
    let len = s.length
    let str = {
			'{':'}',
			'(':')',
			'[':']'
		}
		let stack = []
		for(let i =0;i<len;i++){
			const cur = s[i]
			if(cur == '(' || cur == '[' || cur == '{')  stack.push(str[cur])
			else{
				if(!stack.length || stack.pop() !== cur) return false // 若一开始就右括号,则直接为false
			}
		}
		return !stack.length
};

7、爬楼梯(25)

image-20220308110836166

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第7张图片

题解思路:将递归转为迭代,以优化递归超时
任何递归都可以转为迭代以优化算法

递归解法(会超时) ​ var climbStairs = function(n) { ​ if(n<=2) return n ​ return climbStairs(n-1) + climbStairs(n-2) ​ }

/*
	题解思路:将递归转为迭代,以优化递归超时
	任何递归都可以转为迭代以优化算法
*/
/* 
	递归解法(会超时)
	var climbStairs = function(n) {
		if(n<=2) return n
		return climbStairs(n-1) + climbStairs(n-2)
	}
*/

// 第一种迭代中用变量保存前数值和
var climbStairs = function(n) {
    let a=0,b=0,c=1
    for(let i =0;i<n;i++){
        a=b
        b=c
        c=a+b
    }
    return c
};

// 第二种将前数和保存在数组中
var climbStairs = function(n) {
    if(n<=3) return n
    const arr = new Array(n)
    arr[1] = 1
    arr[2] = 2
    arr[3] = 3
    for(let i = 4;i<=n;i++){
        arr[i] = arr[i-1] + arr[i-2]
    }
    return arr[n]
};

8、全排列(25)

image-20220308112127021

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第8张图片

题解思路:DFS 深度优先遍历字符,并动态保存途径的路径

/*
	题解思路:DFS 深度优先遍历字符,并动态保存途径的路径
*/
var permute = function(nums) {
    let path = []  //  保存途径的路径
    let res = []
    const dfs = (nums)=>{
        if(path.length == nums.length){  // 当路径与数组长度相同时添加路径到结果中
            res.push([...path])
            return
        }   
        for(let i =0;i<nums.length;i++){
            if(path.includes(nums[i])) continue //  如果经过的路径就直接跳过
            path.push(nums[i])  
            dfs(nums)  // 递归找下一条路
            path.pop() // 每次回溯时将经过的路出栈
        }
    }
    dfs(nums)
    return res
};

第三次更新


9、最大子序和(25)

image-20220309100859956

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第9张图片

题解思路:动态规划
​ 在原数组中维护i中最大值,为 i - 1 中与0相比最大的值
​ 并维护最大的值max 与 i下标之间最大的值

/*
	题解思路:动态规划
	在原数组中维护i中最大值,为 i - 1 中与0相比最大的值
	并维护最大的值max 与 i下标之间最大的值
*/

var maxSubArray = function(nums) {
    let max = nums[0]
    let len = nums.length
    for(i=1;i<len;i++){
        nums[i] += Math.max(nums[i-1],0)
        max = Math.max(nums[i],max)
    }
    return max
};

10、 反转链表(22)

image-20220309104410285

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第10张图片

题解思路:链表递归做法

// 递归到最后第2个节点,将它的节点指向null,它的前一个指向自己
var reverseList = function(head) {
    if (head == null || head.next == null) {
        return head;
    }
    const newHead = reverseList(head.next);
    head.next.next = head;
    head.next = null;
    return newHead;
};
// 维护前指针跟当前指针,并将当前指针指向前指针,最后头指针变为pre
var reverseList = function(head) {
    if(!head) return head
    let node = head
    let pre = null,temp
    while(node){
        temp = node.next
        node.next = pre
        pre = node
        node = temp 
    }
    // 最后的头节点变为pre
    return pre
};

11、路径总和(21)

image-20220309105201999

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第11张图片

题解思路:常规树解法

递归或者迭代

/*
	题解思路:迭代法
*/
var hasPathSum = function (root, targetSum) {
    if (!root) return false
    let stack = [[root,root.val]]
    while(stack.length){
        let [node, sum] = stack.pop()
        if(!node.left && !node.right && sum == targetSum) return true  // 当前为叶子节点,并且结果 == targetSum
        if(node.right) stack.push([node.right,node.right.val + sum])
        if(node.left) stack.push([node.left,node.left.val + sum])
    }
    return false
};
/*
	题解思路:递归法
*/
var hasPathSum = function (root, targetSum) {
    if (!root) return false
    let final = false
    const dfs = (node, res) => {
        if (!node.left && !node.right && res == targetSum) final = true // 当前为叶子节点,并且结果 == targetSum
        if(node.left) dfs(node.left, res + node.left.val)
        if(node.right) dfs(node.right, res + node.right.val)
    }
    dfs(root, root.val)
    return final
};

第四次更新


12、二叉树的层序遍历(20)

image-20220310094323178

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第12张图片

题解思路:BFS广度优先搜索

/*
	题解思路:BFS广度优先搜索
*/   
var levelOrder = function(root) {
        if(!root) return []
        let count = 0   //  记录当前层级
        let node = [root]
        let res = []
        while(node.length){
            res[count] = []  //  初始化每层
            let countNum = node.length   //  每层的节点数
            while(countNum--){
                let temp = node.shift()   //  推入每层的节点值
                res[count].push(temp.val)
                if(temp.left) node.push(temp.left)
                if(temp.right) node.push(temp.right)
            }
            count++ // 每层遍历完,推进到下一层
        }
        return res
    };

13、数组中的第K个最大元素(19)

image-20220310094828422

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第13张图片

题解思路:快速排序取对应值

/*
	题解思路:堆排序操作
*/
var findKthLargest = function(nums, k) {
   var len
  // 建立最大堆
  function buildMaxHeap(arr){
    len = arr.length
    // 从非叶子节点开始调整
    for(let i = Math.floor(len/2) ; i>=0;i--){
      heapify(arr,i)
    }
  }
  // 堆调整
  function heapify(arr,i){
      var left = 2*i+1
      var right = 2*i+2
      var largest = i
      if(left < len && arr[left]>arr[largest]){
        largest = left
      }
      if(right < len && arr[right]>arr[largest]){
        largest = right
      }
      if(largest != i){
        swap(arr,i,largest)
        heapify(arr,largest)
      }
    }
  function swap(arr,m,n){
    var temp = arr[m]
    arr[m] = arr[n]
    arr[n] = temp
  }
  function heapSort(arr){
    // 建立最大堆
    buildMaxHeap(arr)
    // 将堆顶元素放到末尾
    for(let i = arr.length-1;i>0;i--){
      swap(arr,0,i)
      len--
      // 每次交换完后调整堆
      heapify(arr,0)
    }
    return arr
  }
  return heapSort(nums)[nums.length-k]
};

14、 三数之和(18)

image-20220310095543901

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第14张图片

题解思路:排序+双指针

/*
	题解思路:排序+双指针
*/
var threeSum = function(nums) {
    let len = nums.length
    if(len < 3 ) return []
    let res = []
    let right 
    let left 
    nums.sort((a,b)=>a-b) // 先将数组按升序排好
    for(let i =0;i<len ;i++){
        if(nums[i] > 0) break    // 如果超过 0 的后面就都不可能满足三位和为0 则直接结束循环
        if(i>0 && nums[i-1] === nums[i]) continue // 如果是重复的则跳过
        left = i+1  // 当前指针的后一位
        right = len - 1  // 数组的最后一位
        while(left < right){ // 开始遍历
            let sum = nums[i] + nums[left] + nums[right]
            if(sum == 0){
                res.push([nums[i],nums[left],nums[right]])
                left++ // 将结果放进取后左指针推进一位,并判断是否有重复,重复就在推进一位
                while(nums[left-1] == nums[left]) left++
            }else if(sum > 0) right--
            else left++
        }
    }
    return res
};

第五次更新


15、环形链表(18)

image-20220311085801142

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第15张图片

题解思路:标记遍历过的链表

//解法一,标记遍历过的链表
var hasCycle = function(head) {
    while(head){
        if(head.flag) return true
        head.flag = true
        head = head.next
    }
    return false
};

//解法二,利用JSON不能转换嵌套循环对象
var hasCycle = function(head) {
    try{
        JSON.stringify(head)
        return false
    }catch{
        return true
    }
};

16、补充题4. 手撕快速排序(18)

image-20220311090130948

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第16张图片

/*
	手撕快排算法
*/
var sortArray = function(nums) {
        if(nums.length <=1) return nums  // 排序到1的时候返回
        let index = Math.floor(nums.length/2) // 找中值
        let pivot = nums.splice(index,1)[0] // 将数组的中值取出
        let left = []
        let right = []
        for(let i =0;i<nums.length;i++){
            if(nums[i] < pivot){
                left.push(nums[i])
            }else{
                right.push(nums[i])
            }
        }
    return [...sortArray(left),pivot,...sortArray(right)]
};

17、 求根节点到叶节点数字之和(18)

image-20220311090337686

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第17张图片

题解思路:dfs深度遍历,并携带路径相加

var sumNumbers = function(root) {
    const dfs = (root,path = 0)=>{
        if(!root) return 0
        path = path * 10 + root.val  // 路径值相加
        if(!root.left && !root.right) return path // 到叶子节点将值返回
        return dfs(root.left,path) + dfs(root.right,path) // 将所有叶子节点的值想加
    }
    return dfs(root)  // 返回结果
};

第六次更新


18、最长回文子串(17)

image-20220312091808601

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第18张图片

var longestPalindrome = function(s) {
	const ds = (m, n) => {
		for( ; ; ){
			if(m >= 0 && n < s.length & s[m] == s[n]){
				m--;
				n++;
			}else{
				break;
			}
		}
		res = n - m - 1 > res.length ? s.slice(m + 1, n) : res;
	}
	if(s.length <= 1){
		return s;
	}
	let res = "";
	for(let i = 0; i < s.length; i++){
		ds(i, i);
		ds(i, i + 1);
	}
	return res;
};

19、买卖股票的最佳时机(14)

image-20220312092934358

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第19张图片

var maxProfit = function(prices) {
    // 创建保存数组中最小值
    let min = prices[0]
    // 记录最大差值
    let max = 0
    let len = prices.length
    for(let i =1;i<len;i++){
        //  在每次循环中记录最小的值
        let cur = prices[i]
        min = Math.min(cur,min)
        //  如果当前值比最小值大则更新最大的差值
        if(cur > min ) max = Math.max(cur - min,max)
    }
    return max
};

20、二分查找(14)

image-20220312093111881

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第20张图片

// 二分查找思路 每次都取一半开始找,并拿中值与目标值标记,若大了就左移,小了就右移
var search = function(nums, target) {
    if(nums.indexOf(target)==-1) return -1
    var low = 0
    var high = nums.length-1
    while(low<=high){
    var mid = Math.floor((low+high)/2)
    if(nums[mid] == target) {return mid}
      else if(nums[mid] < target){
        low = mid + 1
      }else if(nums[mid] > target){
        high = mid - 1
      }
    }
};

第七次更新


21、合并两个有序链表(12)

image-20220313103627062

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第21张图片

题解思路:双指针
​ 先创建一个head新链表结构作为结果放回,
​ 随后遍历list1,list2
​ 将小的值放进新链表里,然后推进新链表与小的值
​ 最后再将链表中剩下的值加进新链表里

/*
	题解思路:双指针
	先创建一个head新链表结构作为结果放回,
	随后遍历list1,list2
	将小的值放进新链表里,然后推进新链表与小的值
	最后再将链表中剩下的值加进新链表里
*/
var mergeTwoLists = function(list1, list2) {
    let head = new ListNode(-1)  //  返回的结果链表
    let preHead = head
    while(list1 && list2){
        if(list1.val < list2.val) 
        {
        preHead.next = list1
        list1 = list1.next
        }
        else{
            preHead.next = list2
            list2 = list2.next
        }
        preHead = preHead.next  // 推进链表
    }
    preHead.next = list1 === null?list2:list1  // 将链表剩下的返回
    return head.next
};	

22、螺旋矩阵(12)

image-20220313104103716

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第22张图片

题解思路:循环一次缩减

将四个方向的数一次循环一遍,

每次循环往内缩

var spiralOrder = function (matrix) {
    if (!matrix.length || !matrix[0].length) return []
    let res = []
    let row = matrix.length - 1, column = matrix[0].length -1
    let left = 0, right = column, top = 0, bottom = row // 四个边界
    while (left <= right && top <= bottom) {  // 每一个数都遍历
        for (let i = left; i <= right; i++) {  // 从左到右边界的循环
            res.push(matrix[top][i])
        }
        for (let i = top + 1; i <= bottom; i++) {  // 从有边界到底的循环
            res.push(matrix[i][right])
        }
        if (top < bottom && left < right) {  //  满足两个条件才说明还有元素可遍历
            for (let i = right - 1; i > left; i--) { // 从右到左不包括左边界
                res.push(matrix[bottom][i])
            }
            for (let i = bottom; i > top; i--) {  //  从底往上遍历不包括上边界
                res.push(matrix[i][left])
            }
        }

        [left, right, top, bottom] = [left + 1, right - 1, top + 1, bottom - 1]  // 边界缩小,往内遍历
    }
    return res
};

23、最长上升子序列(12)

image-20220313104924171

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第23张图片

题解思路:动态规划+两for循环

思路二:排序加二分查找

// 动态规划
var lengthOfLIS = function(nums) {
    if(nums.length <= 1) return nums.length;
    let dp = new Array(nums.length).fill(1);  // 维持一个数组保存每个下标最大的数
    let res = 0;
    for(let i = 1;i<nums.length;i++){
        for(let j = 0;j<i;j++){
            if(nums[i]>nums[j]){
                dp[i] = Math.max(dp[i],dp[j]+1)  // 保持当前下标最大
            }
        }
        if(dp[i]>res) res = dp[i];  // 保存最大结果
    }
    return res;
};
// 排序+二分
var lengthOfLIS = function(nums) {
   const n = nums.length;
   let len = 1;
   if( n == 0) return 0;
   const dp = new Array(n +1);  
   dp[len] = nums[0];
   for(let i = 1;i < n;i++){
       if(nums[i] > dp[len]) dp[++len] = nums[i];
       else {
        // 二分查找 pos 是比 num[i] 最小的数
        let  l = 1, r = len, pos = 0;
        while(l <= r){
            let mid  = Math.floor((r - l) / 2) + l;
            if(dp[mid] < nums[i]){
                pos = mid;
                l = mid + 1;
            }else {r = mid -1 };
        }
         dp[pos + 1] = nums[i]
       }
      
   }
   return len
};

第八次更新


24、 二叉树的中序遍历(12)

image-20220315093047557

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第24张图片

// 迭代法
var inorderTraversal = function(root) {
    if(!root) return []
    let res = []
    let stack = []
    while(stack.length || root){
        // 先遍历到所有左节点
        while(root){
            stack.push(root)
            root = root.left
        }
        let temp = stack.pop()
        res.push(temp.val)
        // 再开始遍历右节点
        root = temp.right
    }
    return res
};
// 递归法
var inorderTraversal = function(root,res = []) {
    if(!root) return []
    if(root.left) inorderTraversal(root.left,res)
    res.push(root.val)
    if(root.right) inorderTraversal(root.right,res)
    return res
};

25、二叉树的最大深度(12)

image-20220315093300925

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第25张图片

//递归加记录最大值
var maxDepth = function (root) {
let max = 0
const dfs = (root,res = 1) => {
    if (!root) return
    if(!root.left && !root.right) max = Math.max(res, max)
    if (root.left) dfs(root.left, res+1)
    if (root.right) dfs(root.right, res+1)
}
dfs(root)
return max
};

26、岛屿数量(11)

image-20220315093555367

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第26张图片

题解思路:遍历到1的,将它的上下左右的1,全变为0

var numIslands = function(grid) {
    let row = grid.length
    let column = grid[0].length
    let count = 0
    for(let i =0;i<row;i++){
        for(let j=0;j<column;j++){
            if(grid[i][j] == '1'){
                count++
                f(i,j)
            }
        }
    }

    function f(row,column){
        // 遍历下
        if(grid[row+1] && grid[row+1][column] == '1'){
            //将遍历到的 1 填为0 防止重复
            grid[row+1][column] = '0'
            f(row+1,column)
        }
        // 遍历上
        if(grid[row-1] && grid[row-1][column] == '1'){
            grid[row-1][column] = '0'
            f(row-1,column)
        }
        // 遍历左
        if(grid[row][column-1] && grid[row][column-1] == '1'){
            grid[row][column-1] = '0'
            f(row,column-1)
        }
        // 遍历右
        if(grid[row][column+1] && grid[row][column+1] == '1'){
            grid[row][column+1] = '0'
            f(row,column+1)
        }
    }
    return count
};

第九次更新


27、零钱兑换(11)

image-20220316092009670

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第27张图片

题解思路:动态规划

var coinChange = function(coins, amount) {
    if(amount == 0) return 0
    let dp = new Array(amount+1).fill(Infinity)
    dp[0] = 0
    let dpLen = dp.length
    let coLen = coins.length
    // 动态规划每个数字对应的最优解
    for(let i=0;i<dpLen;i++){
        for(let j=0;j<coLen;j++){
            if( i - coins[j] < 0 ) continue
            dp[i] = Math.min(dp[i],dp[ i - coins[j] ]+1 )
        }
    }
    return dp[amount] == Infinity?-1:dp[amount]
};

28、剑指 Offer 22. 链表中倒数第k个节点(11)

image-20220316092415020

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第28张图片

var getKthFromEnd = function(head, k) {
    var node = head
    var index = 0
    while(node){
        node = node.next
        index++
    }
    for(let i =0;i<index-k;i++){
        head = head.next
    }
    return head
};

29、括号生成(10)

image-20220316092718142

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第29张图片

/*
	dfs深度遍历,结果满足长度等于n*2即添加
*/
var generateParenthesis = function (n) {
      let res = [];
      //  cur :当前字符  left:当前字符左括号 right:当前字符右括号
      const help = (cur, left, right) => {
        if (cur.length === 2 * n) {
          res.push(cur);
          return;
        }
        if (left < n) {
          help(cur + "(", left + 1, right)
        }
        if (right < left) {
          help(cur + ")", left, right + 1);
        }
      };
      help("", 0, 0);
      return res;
    };

第十次更新


30、最长重复子数组(9)

image-20220317090123344

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第30张图片

var findLength = function (A, B) {
    let maxLength = 0;

    for (let i = 0; i < A.length; i++) {
        if (maxLength >= Math.min(A.length - i, B.length))
            break;

        let len = 0;
        for (let j = 0; j < Math.min(A.length - i, B.length); j++) {
            if (A[i + j] != B[j])
                continue;

            let index = 1;
            while (i + j + index < A.length &&
                j + index < B.length &&
                A[i + j + index] == B[j + index]) {
                index++;
            }
            len = Math.max(len, index);

            j = j + index;
        }

        maxLength = Math.max(maxLength, len);
    }

    for (let i = 1; i < B.length; i++) {
        if (maxLength >= Math.min(B.length - i, A.length))
            break;

        let len = 0;
        for (let j = 0; j < Math.min(B.length - i, A.length); j++) {
            if (B[i + j] != A[j])
                continue;

            let index = 1;
            while (i + j + index < B.length &&
                j + index < A.length &&
                B[i + j + index] == A[j + index]) {
                index++;
            }
            len = Math.max(len, index);

            j = j + index;
        }

        maxLength = Math.max(maxLength, len);
    }

    return maxLength;
};

31、二叉树的前序遍历(9)

image-20220317090714758

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第31张图片

// 递归法
var preorderTraversal = function(root,res=[]) {
    if(!root) return []
    res.push(root.val)
    preorderTraversal(root.left,res)
    preorderTraversal(root.right,res)
    return res
};
// 迭代法
var preorderTraversal = function(root) {
    if(!root) return []
    let res = []
    let queue = [root]
    while(queue.length){
        let temp = queue.pop()
        res.push(temp.val)
        if(temp.right) queue.push(temp.right)
        if(temp.left) queue.push(temp.left)
    }
    return res
};

32、合并区间(9)

image-20220317090909303

力扣 --- CodeTop --- 2022前端高频面试算法题归纳详解,附带面试中出现频率,冲刺面试算法(JS实现)(持续更新中、)_第32张图片

// 题解思路,先排序再进行比较
var merge = function(intervals) {
    intervals.sort((a,b)=>a[0] - b[0])  // 将数组区间,按首数字进行排序
    let res = [intervals[0]] // 初始化比较数组
    let len = intervals.length 
    for(let i =1;i<len;i++){
        if(res[res.length - 1][1] >= intervals[i][0] ){ // 当结果数组数组区间的最后一位数,在比较数组的区间内
            res[res.length - 1][1] = Math.max(res[res.length - 1][1],intervals[i][1])  // 将结果数组数组区间的最后一位数换成最大的那个
        }else{
            res.push(intervals[i]) // 不然就添加到结果中
        }
    }
    return res
};

你可能感兴趣的:(剑指offer,--,javascript,力扣,面试,leetcode,算法)