算法题(图论)

一、题目

1、课程表(LC 207)

2、实现 Trie 前缀树(LC 208)

二、题解

1、课程表(LC 207)

(1)分析

根据给定的课程总数与课程先修关系,判断是否存在无法完成所有课程学习的情况,本质就是给一个有向图,判断有向图中是否有环。将课程与先修关系转化为有向图结构,每一门课程对应图中的一个节点,课程之间的先修约束对应有向边,例如修课程 2 必须先完成课程 1 的学习,就构建一条从节点 1 指向节点 2 的有向边。

采用拓扑排序的方法解决。创建入度数组,每一门课程所需的先修课程数量,数组下标对应课程编号,数组值即为该课程的入度;邻接表记录课程的后续课程;队列存储当前入度为 0 的课程,这类课程没有任何先修约束,是可以直接开始学习的课程。

在循环处理过程中,每次从队列头部取出一个课程节点,代表该课程已成功修读,同时将总课程数减一,随后遍历该课程的所有后续课程,将这些后续课程的入度依次减一,代表完成了一个先修条件,若某门后续课程的入度减至 0,说明其所有先修课程均已完成,将其加入队列继续处理。当队列为空时,循环执行结束,此时判断剩余的总课程数是否为 0 ,若剩余课程数为 0,说明图中无环,可以修完所有课程,若剩余课程数大于 0,说明存在部分课程始终无法进入队列,即图中存在环,无法完成学习。

(2)解答
java 复制代码
class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        int[] inDegree = new int[numCourses];    
//记录入度的数组,如inDgree[0] = 2,表示修课程0需要先修2个其他课程   
                                                  
        List<List<Integer>> list = new ArrayList<>();
//邻接表,存储每门课程的后续课程,list.get(0),得到的就是需要先修课程0,才能修的课程

        Queue<Integer> queue = new LinkedList<>();
//队列存储入度为0的课程,即现在可以直接修的课程

        for(int i = 0; i < numCourses; i++){
            list.add(new ArrayList<>());
        }
        for(int[] arr : prerequisites){
            inDegree[arr[0]]++;
            list.get(arr[1]).add(arr[0]); 
        }
//初始化邻接表,初始化入度数组

        for(int i = 0; i < numCourses; i++){
            if(inDegree[i] == 0){
                queue.offer(i);
            }
        }
//初始化入度为0的队列

//BFS
        while(!queue.isEmpty()){
            Integer i = queue.poll();   //取出一个队首元素,代表修了一门课程
            numCourses--; 
            for(int j : list.get(i)){
                inDegree[j]--;         //更新入度数组
                if(inDegree[j] == 0){  //入度数组中,某个课程对应下标的入度为0,加入队列
                    queue.offer(j);
                }
            }
        }
        return numCourses == 0;      //循环结束后课程数为零,代表可以修完
    }
}

2、实现 Trie 前缀树(LC 208)

(1)分析

创建二十六叉数,类似于二叉树,有节点数组 son 存放26个子节点,属性 end 代表是否为字符末尾。inesrt函数,从根节点出发,将字符串逐字符转换为数组遍历,对于每一个字符,计算其在子节点数组中的下标,若当前节点的对应下标位置为空,则创建新的节点构建路径,若已存在节点则直接复用,遍历完成所有字符后,将最后一个节点的 end 属性设为 true,标识该节点是一个完整字符串的结尾。

查找完整字符串 search 和查找前缀 startwith 功能共用一个 find 函数,遍历目标字符串对应的所有节点路径,若遍历过程中遇到空节点,说明前缀树中不存在该路径,返回标识 0,若完整遍历完所有字符且路径存在,则根据最后一个节点的 end 属性判断,若 end 为 false 说明仅为前缀,返回标识 1,若 end 为 true 说明是完整字符串,返回标识 2。

(2)解答
java 复制代码
class Trie {

    private static class Node{
        Node[] son = new Node[26];
        boolean end = false;
    }

    Node root = new Node();

    public Trie() {
        
    }
    
    public void insert(String word) {
       Node curr = root;
       for(char ch : word.toCharArray()){
        int index = ch - 'a';
        if(curr.son[index] == null){
            curr.son[index] = new Node();
        }
        curr = curr.son[index];
       } 
       curr.end = true;
    }
    
    public boolean search(String word) {
        int i = find(word);
        if(i == 2){
            return true;
        }
        return false;
        
    }
    
    public boolean startsWith(String prefix) {
        int i = find(prefix);
        if(i != 0){
            return true;
        }
        return false;
        
    }

    public int find(String str){
        Node curr = root;
        for(char ch : str.toCharArray()){
            int index = ch - 'a';
            if(curr.son[index] == null){
                return 0;
            }
            curr = curr.son[index];
        }
        return curr.end == false ? 1 : 2;
    }
}

/**
 * Your Trie object will be instantiated and called as such:
 * Trie obj = new Trie();
 * obj.insert(word);
 * boolean param_2 = obj.search(word);
 * boolean param_3 = obj.startsWith(prefix);
 */
相关推荐
Pkmer14 小时前
滑动窗口专题
算法
Omics Pro14 小时前
柳叶刀|参考文献不存在
人工智能·算法·机器学习·支持向量机·自然语言处理
初心未改HD14 小时前
机器学习之K-Means聚类算法详解
算法·机器学习·kmeans
yugi98783814 小时前
主动噪声控制中的 FXLMS 算法研究与 MATLAB 实现
开发语言·算法·matlab
Liangwei Lin15 小时前
LeetCode 394. 字符串解码
数据结构·算法
YuanDaima204815 小时前
动态规划基础原理与题目说明
数据结构·人工智能·python·算法·动态规划·手撕代码
大志出奇迹15 小时前
传输协议为大端,STM32为小端,数据传输的字节序问题
c语言·stm32·单片机·mcu·算法·rtos
我爱cope15 小时前
【滑动窗口:力扣438找到字符串中所有字母异位词】
算法·leetcode·职场和发展
happyprince15 小时前
06-FlagEmbedding 核心算法详解
算法
洛水水15 小时前
【力扣100题】27. 二叉树的最大深度
算法·leetcode·图论