首页 > 编程语言 >【JavaScript】LeetCode:61-65

【JavaScript】LeetCode:61-65

时间:2024-10-12 18:52:33浏览次数:10  
标签:return nums trie JavaScript 61 length let path LeetCode

文章目录

61 课程表

在这里插入图片描述

  • Map + BFS
  • 拓扑排序:将有向无环图转为线性顺序。
  • 遍历prerequisites:1. 数组记录每个节点的入度,2. 哈希表记录依赖关系。
  • n = 6,prerequisites = [ [3,0],[3,1],[4,1],[4,2],[5,3],[5,4] ]。
    0、1、2的入度为0,3、4、5的入度为2。
    map:0:[3],1:[3,4],2:[4],3:[5],4:[5]。
  • 创建队列,将入度为0的节点入队。
  • 陆续将入度为0的节点从队列中弹出,直至队列为空。入度为0的节点不需要学习先修课程,所以可以直接选。
  • 每弹出一个节点,就将该节点对应后续课程的入度 - 1,并将入度为0的节点加入队列。
  • count记录选课的数量,每弹出一个节点,count++,最后判断count是否等于总课数。
/**
 * @param {number} numCourses
 * @param {number[][]} prerequisites
 * @return {boolean}
 */
var canFinish = function(numCourses, prerequisites) {
    let pre = new Array(numCourses).fill(0);
    let map = new Map();
    for(let i = 0; i < prerequisites.length; i++){
        pre[prerequisites[i][0]] += 1;
        if(!map.has(prerequisites[i][1])){
            map.set(prerequisites[i][1], [prerequisites[i][0]]);
        }else{
            map.get(prerequisites[i][1]).push(prerequisites[i][0]);
        }
    }
    let queue = [];
    let count = 0;
    for(let j = 0; j < numCourses; j++){
        if(pre[j] == 0){
            queue.push(j);
        }
    }
    while(queue.length != 0){
        let item = queue.shift();
        count += 1;
        let cls = map.get(item);
        if(cls != undefined){
            for(let k = 0; k < cls.length; k++){
                pre[cls[k]] -= 1;
                if(pre[cls[k]] == 0){
                    queue.push(cls[k]);
                }
            }
        }
    }
    return count == numCourses;
};

62 实现Trie(前缀树)

在这里插入图片描述

  • 前缀树,又称字典树、单词查找树。

  • isEnd:记录该节点是否为最后一个节点(单词的结尾)。

  • Trie:保存了当前节点(字母)的下一个出现的所有字符。

  • 例如:sea,sels,she组成的前缀树如下所示。

  •         s

  •     /       \

  •   e          h

  •  /   \          \

  • a     l          e

  •        |

  •        s

  • 插入:向Trie中插入一个单词。
    从根结点开始与单词的第一个字符进行匹配,一直匹配到前缀链上没有对应的字符,这时开始不断开辟新的结点,直到插入完单词的最后一个字符,并将最后一个结点isEnd = true,表示它是一个单词的末尾。

  • 查找:查找Trie中是否存在单词word。
    从根结点开始一直向下匹配,如果前缀链上没有对应的字符就返回false,如果直到最后一个字符都匹配,则返回所匹配最后一个节点的isEnd。

  • 前缀匹配:判断Trie中是否有以prefix为前缀的单词。
    和查找类似,只是不需要判断最后一个字符结点的isEnd,因为既然能匹配到最后一个字符,就一定有单词以prefix为前缀。

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

/** 
 * @param {string} word
 * @return {void}
 */
Trie.prototype.insert = function(word) {
    let trie = this.children;
    for(let i of word){
        if(trie[i] == null){
            trie[i] = new Trie();
        }
        trie = trie[i];
    }
    trie.isEnd = true;
};

/** 
 * @param {string} word
 * @return {boolean}
 */
Trie.prototype.search = function(word) {
    let trie = this.children;
    for(let i of word){
        if(trie[i] == null){
            return false
        }
        trie = trie[i];
    }
    return trie.isEnd;
};

/** 
 * @param {string} prefix
 * @return {boolean}
 */
Trie.prototype.startsWith = function(prefix) {
    let trie = this.children;
    for(let i of prefix){
        if(trie[i] == null){
            return false
        }
        trie = trie[i];
    }
    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)
 */

63 全排列

在这里插入图片描述

  • 递归
  • 设置used数组,标记已经选择的元素。
  • for循环横向遍历,递归纵向遍历。
  • 递归出口:收集元素的数组path的length = 数组nums的length,此时到达叶子节点,找到了一个全排列,收集路径path。
  • 注意:在结果数组res中放路径时,应使用 path .slice(),因为如果使用path,后续path的改变会影响存放在res的path。
/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var permute = function(nums) {
    var traversal = function(nums, used){
        if(path.length == nums.length){
            res.push(path.slice());
            return;
        }
        for(let i = 0; i < nums.length; i++){
            if(used[i] == 0){
                path.push(nums[i]);
                used[i] = 1;
                traversal(nums, used);
                path.pop();
                used[i] = 0;
             }
        }
    }
    let used = Array(nums.length).fill(0);
    let path = [];
    let res = [];
    traversal(nums, used);
    return res;
};

64 子集

在这里插入图片描述

  • 递归
  • 设置startIndex,标记遍历开始的位置。
  • for循环横向遍历,递归纵向遍历。
  • 子集与全排列不同,需要记录所有的节点,而不只是叶子节点。
  • 每次进入递归都要收集子集。
  • 递归出口:startIndex > nums的length,此时没有元素可取了。
/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var subsets = function(nums) {
    var traversal = function(nums, startIndex){
        res.push(path.slice());
        if(startIndex == nums.length){
            return;
        }
        for(let i = startIndex; i < nums.length; i++){
            path.push(nums[i]);
            traversal(nums, i + 1);
            path.pop();
        }
    }
    let res = [];
    let path = [];
    traversal(nums, 0);
    return res;
};

65 电话号码的字母组合

在这里插入图片描述

  • 递归
  • 定义map数组映射数字和字母。
  • for循环横向遍历,字母的个数为for循环的遍历次数;递归纵向遍历,digits的长度为递归深度。
  • 设置index,记录遍历到digits的第几个数字了。
  • 递归出口:index = digits的length,此时到达叶子节点,收集结果。
/**
 * @param {string} digits
 * @return {string[]}
 */
var letterCombinations = function(digits) {
    var traversal = function(digits, index){
        if(index == digits.length){
            res.push(path.slice().join(""))
            return;
        }
        let all = map[digits[index] - '0'];
        for(let item of all){
            path.push(item);
            traversal(digits, index + 1);
            path.pop();
        }
    }
    let map = ["", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"];
    let path = [];
    let res = [];
    if(digits.length == 0){
        return res;
    }
    traversal(digits, 0);
    return res;
};

标签:return,nums,trie,JavaScript,61,length,let,path,LeetCode
From: https://blog.csdn.net/weixin_45980065/article/details/142874021

相关文章

  • leetcode 179. Largest Number
    179.LargestNumber要比较拼接以后谁应该放在前面,先试着把他们拼起来就行了然后因为正着拼和反着拼,长度一致,所以自带的string比较函数会严格比较他们的大小关系,不会因为字符串长度而误判boolcmp(constint&a,constint&b);classSolution{public:std::string......
  • 2024.10.12 1615版
    起于《海奥华预言》的思考◆地球管理结构和参考持续更新中...... 英文地址:https://github.com/zhuyongzhe/Earth/tags中文地址:https://www.cnblogs.com/zhuyongzhe85作者:朱永哲 ---------------------------------------------------------------------------------......
  • 代码随想录训练营第五天|Leetcode.349,Leetcode.454,Leetcode19,Leetcode18
    一、哈希表和set和map和数组的关系 用哈希表,判断是否出现过。数值很大或者数值很分散时,不用数组,占用空间大,用set。set,multiset数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判......
  • 前后端分离nodejs_vue+javascript个人身体健康档案管理系统
    目录技术栈具体实现截图开发工具和技术简介错误处理和异常处理nodejs类核心代码部分展示解决的思路其他题目推荐源码获取/联系我技术栈该系统将采用B/S结构模式,开发软件有很多种可以用,本次开发用到的软件是vscode,用到的数据库是MySQL,为了更加便捷地使用数据库,用到了......
  • JavaScript原型链污染漏洞分析
    原型链污染漏洞CVE:1、yargs-Parser输入验证错误漏洞(CVE-2020-7608)2、tough-cookie安全漏洞(CVE-2023-26136)3、JSON5原型污染漏洞(CVE-2022-46175) 漏洞描述:1、yargs-Parser输入验证错误漏洞(CVE-2020-7608):yargs-parser是一款选项解析器。yargs-parser13.1.2之前......
  • Leetcode 1192. 查找集群内的关键连接
    1.题目基本信息1.1.题目描述力扣数据中心有n台服务器,分别按从0到n-1的方式进行了编号。它们之间以服务器到服务器的形式相互连接组成了一个内部集群,连接是无向的。用connections表示集群网络,connections[i]=[a,b]表示服务器a和b之间形成连接。任何服务器都可......
  • JavaScript
    什么是JavaScript?Web标准也称为网页标准,由一系列的标准组成,大部分由W3C(WorldWideWebConsortium,万维网联盟)负责制定。三个组成部分:HTML:负责网页的基本结构(页面元素和内容)。CSS:负责网页的表现效果(页面元素的外观、位置等页面样式,如:颜色、大小等)。JavaScript:负责网页的......
  • 大学生HTML期末大作业——HTML+CSS+JavaScript购物商城(篮球)
    HTML+CSS+JS【购物商城】网页设计期末课程大作业web前端开发技术web课程设计网页规划与设计......
  • 大学生HTML期末大作业——HTML+CSS+JavaScript培训机构(英语教育)
    HTML+CSS+JS【培训机构】网页设计期末课程大作业web前端开发技术web课程设计网页规划与设计......
  • JavaScript 第4章:函数与作用域
    在JavaScript中,函数是程序设计中的重要组成部分,它们用于封装一段代码以执行特定的任务。下面我们将逐一探讨第4章提到的各个概念。1.函数声明vs函数表达式函数声明(FunctionDeclaration)是使用function关键字定义一个函数,并给它命名的一种方式。这种方式定义的函数会......