算法题(图论)

一、题目

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);
 */
相关推荐
YH55269841 小时前
GPT‑5.6 Sol 原本支持 1M 上下文,Codex 现已放开此前限制,如何看待这次调整?
java·jvm·人工智能·gpt·算法·chatgpt
遥感知识服务3 小时前
从局部阈值、双极化到暗地表剔除:NASA OPERA DSWx-S1全球动态水体算法拆解
大数据·人工智能·深度学习·神经网络·算法·机器学习
晚风醉蝶3 小时前
1-13-TimSort
算法
ZJU_统一阿萨姆3 小时前
【算子开发】算子融合与Softmax_LayerNorm实现
人工智能·算法·语言模型·硬件架构
叩码以求索5 小时前
浅谈:前序遍历反转法求解N叉树的后序遍历
算法
北风toto6 小时前
中缀、前缀、后缀表达式
算法·软件设计师
听取WA声一片(无恶意)6 小时前
CSP-J/CSP-S 深度优先搜索(DFS)完全讲义
c++·算法·深度优先
码流怪侠7 小时前
2026年8月GitHub热榜深度拆解:Agent Skills席卷开源圈,一个“技能包“收割5万星
算法·程序员·github
hold?fish:palm7 小时前
30 两两交换链表中的节点
数据结构·算法·链表
Nil2087 小时前
leetcode 98验证二叉搜索树
算法·leetcode·职场和发展