当前位置: 首页 > news >正文

LeetCode热题100JS(54/100)第十天|124|200|994|207|208

 124. 二叉树中的最大路径和

题目链接:124. 二叉树中的最大路径和

难度:困难

刷题状态:1刷

新知识:

解题过程

思考

示例 1:

输入:root = [1,2,3]
输出:6
解释:最优路径是 2 -> 1 -> 3 ,路径和为 2 + 1 + 3 = 6

没思路,看答案

题解分析

参考题解链接:​​​​​​​二叉树中的最大路径和

详细分析如下

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var maxPathSum = function(root) {
    let res=-Infinity
    //该函数用来求子树最大链(单边)
    function dfs(node){
        if(!node) return 0
        let lval=dfs(node.left)//左子树最大链和
        let rval=dfs(node.right)//右子树最大链和
        //更新最大路径和
        res=Math.max(res,lval+rval+node.val)
        //返回最大子树链
        return Math.max(0,Math.max(lval,rval)+node.val)
    }
    dfs(root)    
    return res
};

手搓答案(无非废话版)

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var maxPathSum = function(root) {
    let res=-Infinity
    function dfs(node){
        if(!node) return 0
        let lval=dfs(node.left)
        let rval=dfs(node.right)
        res=Math.max(res,lval+rval+node.val)
        return Math.max(0,Math.max(lval,rval)+node.val)
    }
    dfs(root)
    return res
};

总结

 注意dfs函数是求最大子数链和,包括node.val本身

 ​​​​​​​200. 岛屿数量

题目链接:​​​​​​​​​​​​​​200. 岛屿数量

难度:中等

刷题状态:1刷

新知识:

解题过程

思考

示例 1:

输入:grid = [
  ["1","1","1","1","0"],
  ["1","1","0","1","0"],
  ["1","1","0","0","0"],
  ["0","0","0","0","0"]
]
输出:1

图论类型的题,没思路直接看答案

题解分析

参考题解链接:​​​​​​​200. 岛屿数量(DFS / BFS)

详细分析如下

/**
 * @param {character[][]} grid
 * @return {number}
 */
var numIslands = function(grid) {
    //dfs函数的作用是把grid[i][j]所在的岛全都变成0
    function dfs(grid,i,j){
        //注意grid[i][j]必须要放在最后面
        if(i<0||i>=grid.length||j<0||j>=grid[0].length||grid[i][j]=='0') return 
        //1=>0
        grid[i][j]='0'
        //遍历上下左右
        dfs(grid,i-1,j)
        dfs(grid,i+1,j)
        dfs(grid,i,j-1)
        dfs(grid,i,j+1)
    }
    let count=0
    for(let i=0;i<grid.length;i++){
        for(let j=0;j<grid[0].length;j++){
            if(grid[i][j]=='1'){
                dfs(grid,i,j)
                count++
            }
        }
    }
    return count
};

手搓答案(无非废话版)

/** 
 * @param {character[][]} grid
 * @return {number}
 */
var numIslands = function(grid) {
    function dfs(grid,i,j){
        if(i<0||i>=grid.length||j<0||j>=grid[0].length||grid[i][j]=='0') return 
        grid[i][j]='0'
        dfs(grid,i-1,j)
        dfs(grid,i+1,j)
        dfs(grid,i,j-1)
        dfs(grid,i,j+1)
    }
    let count=0
    for(let i=0;i<grid.length;i++){
        for(let j=0;j<grid[0].length;j++){
            if(grid[i][j]=='1'){
                dfs(grid,i,j)
                count++
            }            
        }
    }
    return count
};

总结

注意要先判断i,j的范围,再判断是否到边界了,grid[i][j]

 ​​​​​​​994. 腐烂的橘子

题目链接:​​​​​​​​​​​​​​994. 腐烂的橘子

难度:中等

刷题状态:1刷

新知识:

解题过程

思考

示例 1:

输入:grid = [[2,1,1],[1,1,0],[0,1,1]]
输出:4

没思路,看答案

题解分析

参考题解链接:​​​​​​​​​​​​​​多源 BFS,附题单(Python/Java/C++/Go/JS/Rust)

详细分析如下

/**
 * @param {number[][]} grid
 * @return {number}
 */
var orangesRotting = function(grid) {
    //m行数,n列数
    let m=grid.length,n=grid[0].length
    //新鲜橘子数量
    let fresh=0
    //腐烂橘子的坐标
    let q=[]
    for(let i=0;i<m;i++){
        for(let j=0;j<n;j++){
            if(grid[i][j]==1){
                fresh++
            }else if(grid[i][j]==2){
                q.push([i,j])
            }
        }
    }

    let res=0
    //如果q为0了,说明所有临近的橘子都被遍历过了
    //如果此时还有fresh的橘子,说明,不会全部腐烂
    while(fresh&&q.length){
        res++//经过一分钟
        //存q
        let tmp=q
        q=[]
        for(let [x,y] of tmp){//已经腐烂的橘子
        //四个方向上的橘子
            for(let [i,j] of [[x-1,y],[x+1,y],[x,y-1],[x,y+1]]){
                if(0<=i&&i<m&&0<=j&&j<n&&grid[i][j]==1){
                    fresh--
                    grid[i][j]=2//变成腐烂橘子
                    q.push([i,j])
                }
            }
        }
    }
    return fresh?-1:res
};

手搓答案(无非废话版)

/**
 * @param {number[][]} grid
 * @return {number}
 */
var orangesRotting = function(grid) {
    let fresh=0,q=[]
    for(let i=0;i<grid.length;i++){
        for(let j=0;j<grid[0].length;j++){
            if(grid[i][j]==1){
                fresh++
            }else if(grid[i][j]==2){
                q.push([i,j])
            }
        }
    }
    let res=0
    while(fresh&&q.length){
        res++
        let tmp=q
        q=[]
        for(let [x,y] of tmp){
            for(let [i,j] of [[x-1,y],[x+1,y],[x,y-1],[x,y+1]]){
                if(i>=0&&i<grid.length&&j>=0&&j<grid[0].length&&grid[i][j]==1){
                    fresh--
                    grid[i][j]=2
                    q.push([i,j])
                }
            }
        }
    }
    return fresh?-1:res
};

总结

 注意fresh和q这两个变量设置的意义和作用,本题用的是BFS方法

 ​​​​​​​​​​​​​​207. 课程表

题目链接:​​​​​​​​​​​​​​​​​​​​​207. 课程表

难度:中等

刷题状态:1刷

新知识:

解题过程

思考

示例 1:

输入:numCourses = 2, prerequisites = [[1,0]]
输出:true
解释:总共有 2 门课程。学习课程 1 之前,你需要完成课程 0 。这是可能的。

图论类型的题,没思路直接看答案

题解分析

参考题解链接:​​​​​​​​​​​​​​课程表(拓扑排序:入度表BFS法 / DFS法,清晰图解)

详细分析如下

/**
 * @param {number} numCourses
 * @param {number[][]} prerequisites
 * @return {boolean}
 */
var canFinish = function (numCourses, prerequisites) {
    //用于存储每个课程的 入度 信息
    let inDegree=Array(numCourses).fill(0)
    //map用来存学完pre[1]才能学习pre[0]
    let map=new Map()
    for(let pre of prerequisites){
        //到pre[0]的路径+1
        inDegree[pre[0]]++
        //如果map里面没有起点pre[1],就存一个新的起点
        if(!map.has(pre[1])){
            map.set(pre[1],[pre[0]])
        }else{
            //如果有的话说明有共同起点,push到pre[1]那一项里面
            let arr=map.get(pre[1])
            arr.push(pre[0])
            map.set(pre[1],arr)
        }
    }
    let q=[]
    for(let i=0;i<numCourses;i++){
        //如果入度为0,说明现在可以学习,把这些课程加入q
        if(inDegree[i]==0) q.push(i)
    }
    let num=numCourses
    while(q.length>0){
        //获取q的第一个元素
        let tmp=q.shift()
        num--
        //现在学完了pre[1],看一下pre[1]学完了能学什么pre[0]
        let arr=map.get(tmp)||[]
        for(let a of arr){
            //把能学的pre[0]入度减1
            inDegree[a]--
            //如果入度为0,说明下次就可以学了
            if(inDegree[a]==0) q.push(a)
        }
    }
    return num?false:true
}

手搓答案(无非废话版)

/**
 * @param {number} numCourses
 * @param {number[][]} prerequisites
 * @return {boolean}
 */
var canFinish = function (numCourses, prerequisites) {
    let inDegree=new Array(numCourses).fill(0)
    for(let pre of prerequisites) inDegree[pre[0]]++
    let map=new Map()
    for(let pre of prerequisites){
        if(!map.has(pre[1])){
            map.set(pre[1],[pre[0]])
        }else{
            map.get(pre[1]).push(pre[0])
        }
    }
    let num=numCourses,q=[]
    for(let i=0;i<num;i++){
        if(inDegree[i]==0) q.push(i)
    }
    while(q.length){
        let tmp=q.shift()
        num--
        let next=map.get(tmp)||[]
        for(let n of next){
            inDegree[n]--
            if(inDegree[n]==0) q.push(n)
        }
    }
    return num?false:true
}

总结

这道题好难啊,,,主要是要设置的存数据的变量很多,注意这里要设置let next=map.get(tmp)||[],如果不存在tmp学完的下一个,要给它赋初值[]

  ​​​​​​​208. 实现 Trie (前缀树)

题目链接:​​​​​​​208. 实现 Trie (前缀树)

难度:中等

刷题状态:1刷

新知识:

解题过程

思考

示例:

输入
["Trie", "insert", "search", "search", "startsWith", "insert", "search"]
[[], ["apple"], ["apple"], ["app"], ["app"], ["app"], ["app"]]
输出
[null, null, true, false, true, null, true]

解释
Trie trie = new Trie();
trie.insert("apple");
trie.search("apple");   // 返回 True
trie.search("app");     // 返回 False
trie.startsWith("app"); // 返回 True
trie.insert("app");
trie.search("app");     // 返回 True

没思路,看答案

题解分析

参考题解链接:​​​​​​​​​​​​​​Trie Tree 的实现 (适合初学者)🌳

详细分析如下


var Trie = function() {
    this.isEnd=false
    this.next={}//用对象来存储子节点,模拟哈希表
};

/** 
 * @param {string} word
 * @return {void}
 */
 //插入一个单词到字典树中
Trie.prototype.insert = function(word) {
    let node=this
    for(let char of word){
        //将字符转换为0-25的索引(假设只处理小写字母)
        let charCode=char.charCodeAt(0)-97
        if(!node.next[charCode]) node.next[charCode]=new Trie()
        node=node.next[charCode] 
    }
    node.isEnd=true
};

/** 
 * @param {string} word
 * @return {boolean}
 */
 //搜索一个单词是否在字典中
Trie.prototype.search = function(word) {
    let node=this
    for(let char of word){
        let charCode=char.charCodeAt(0)-97
        node=node.next[charCode]
        if (!node) return false
    }
    return node.isEnd
};

/** 
 * @param {string} prefix
 * @return {boolean}
 */
 //检查是否存在以,给定前缀 ,开头的单词
Trie.prototype.startsWith = function(prefix) {
    let node=this
    for(let char of prefix){
        let charCode=char.charCodeAt(0)-97
        node=node.next[charCode]
        if(!node) return false
    }
    return true
};

/** 
 * Your Trie object will be instantiated and called as such:
 * var obj = new Trie()
 * obj.insert(word)
 * var param_2 = obj.search(word)
 * var param_3 = obj.startsWith(prefix)
 */

手搓答案(无非废话版)

var Trie=function(){
    this.isEnd=false
    this.next={}
}

/**
 * @param {string} word
 * @return {void}
 */
Trie.prototype.insert=function(word){
    let node=this
    for(let char of word){
        let charCode=char.charCodeAt(0)-97
        if(!node.next[charCode]) node.next[charCode]=new Trie()
        node=node.next[charCode]
    }
    node.isEnd=true
}

/**
 * @param {string} word
 * @return {void}
 */
Trie.prototype.search=function(word){
    let node=this
    for(let char of word){
        let charCode=char.charCodeAt(0)-97
        node=node.next[charCode]
        if(!node) return false
    }
    return node.isEnd
}  

/**
 * @param {string} word
 * @return {void}
 */
Trie.prototype.startsWith=function(word){
    let node =this
    for(let char of word){
        let charCode=char.charCodeAt(0)-97
        node=node.next[charCode]
        if (!node) return false
    }
    return true
}

总结

 函数定义类型的题目,有固定思路

相关文章:

  • 数图亮相第三届全国生鲜创新峰会,赋能生鲜零售数字化转型
  • 【力扣100】简要总结之哈希
  • 配置blender的python环境
  • 红黑树的部分实现(C++)
  • IPD解读——IPD重构产品研发与产品管理
  • C程序设计(第五版)及其参考解答,附pdf
  • Android开源库——RxJava和RxAndroid
  • 前端传参+后端接参对照
  • java项目40分钟后token失效问题排查(40分钟后刷新页面白屏)
  • Qt for WebAssembly程序中文乱码问题处理过程
  • LLVM学习-- 构建和安装
  • Leetcode 3485. Longest Common Prefix of K Strings After Removal
  • 较为完善的搜索函数
  • LangChain 动态任务分发:开启大模型任务流的巅峰之术(三)
  • CRMEB标准版/开源版商城系统【遇坑解决】
  • 3.5 二分查找专题:LeetCode 852. 山脉数组的峰值
  • 单片机自学总结
  • 如何搭建一个安全经济适用的TRS交易平台?
  • Linkreate wordpressAI插件 24小时自动生成原创图文,新增从百度、必应搜索引擎自动获取相关下拉关键词
  • SpringBoot第三站(4):配置嵌入式服务器使用外置的Servlet容器
  • 中行一季度净赚超543亿降2.9%,利息净收入降逾4%
  • 发布亮眼一季度报后,东阿阿胶股价跌停:现金流隐忧引发争议
  • 历史新高!上海机场一季度营收增至31.72亿元,净利润增34%
  • 今年我国电影票房破250亿领跑全球,“电影+”带动文旅消费热潮
  • 民调显示特朗普执政百日支持率为80年来美历任总统最低
  • 四川落马厅官周海琦受审,1000多人接受警示教育