5.20 图、树
This commit is contained in:
parent
a900792e79
commit
353b7c0267
@ -30,4 +30,31 @@ public class MaxSubArray {
|
||||
}
|
||||
return maxsum;
|
||||
}
|
||||
//假设还要同时返回起始结束下标:
|
||||
public int[] maxSubArray2(int[] nums) {
|
||||
int tempsum = nums[0]; // 当前子数组的和
|
||||
int maxsum = nums[0]; // 最大子数组和
|
||||
int start = 0; // 最大子数组的起始下标
|
||||
int end = 0; // 最大子数组的结束下标
|
||||
int tempStart = 0; // 当前子数组的起始下标
|
||||
|
||||
for (int i = 1; i < nums.length; i++) {
|
||||
if (tempsum < 0) {
|
||||
tempsum = nums[i]; // 如果当前子数组和为负数,则重新从当前元素开始
|
||||
tempStart = i; // 更新当前子数组的起始下标
|
||||
} else {
|
||||
tempsum += nums[i]; // 否则,继续扩展当前子数组
|
||||
}
|
||||
|
||||
// 如果当前的子数组和大于之前的最大和,则更新最大和和区间的下标
|
||||
if (tempsum > maxsum) {
|
||||
maxsum = tempsum;
|
||||
start = tempStart; // 记录最大子数组的起始下标
|
||||
end = i; // 记录最大子数组的结束下标
|
||||
}
|
||||
}
|
||||
|
||||
// 返回最大子数组的和以及起始和结束下标
|
||||
return new int[] {maxsum, start, end};
|
||||
}
|
||||
}
|
||||
|
56
src/main/java/array/MaxSubarraySumCircular.java
Normal file
56
src/main/java/array/MaxSubarraySumCircular.java
Normal file
@ -0,0 +1,56 @@
|
||||
package array;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
/**
|
||||
* 题目: 918. 环形子数组的最大和 (maxSubarraySumCircular)
|
||||
* 描述:给定一个长度为 n 的环形整数数组 nums ,返回 nums 的非空 子数组 的最大可能和 。
|
||||
*
|
||||
* 环形数组 意味着数组的末端将会与开头相连呈环状。形式上, nums[i] 的下一个元素是 nums[(i + 1) % n] , nums[i] 的前一个元素是 nums[(i - 1 + n) % n] 。
|
||||
*
|
||||
* 子数组 最多只能包含固定缓冲区 nums 中的每个元素一次。形式上,对于子数组 nums[i], nums[i + 1], ..., nums[j] ,不存在 i <= k1, k2 <= j 其中 k1 % n == k2 % n 。
|
||||
*
|
||||
示例 1:
|
||||
输入:nums = [1,-2,3,-2]
|
||||
输出:3
|
||||
解释:从子数组 [3] 得到最大和 3
|
||||
*
|
||||
* 链接:https://leetcode.cn/problems/maximum-sum-circular-subarray/
|
||||
|
||||
*/
|
||||
//不会
|
||||
public class MaxSubarraySumCircular {
|
||||
//很巧妙的思路
|
||||
public int maxSubarraySumCircular(int[] nums) {
|
||||
int totalSum = 0; // 数组元素总和
|
||||
int currMax = 0; // Kadane 当前最大子数组和
|
||||
int maxSum = Integer.MIN_VALUE; // 全局最大子数组和
|
||||
|
||||
int currMin = 0; // Kadane 当前最小子数组和
|
||||
int minSum = Integer.MAX_VALUE; // 全局最小子数组和
|
||||
|
||||
for (int x : nums) {
|
||||
// 累加总和
|
||||
totalSum += x;
|
||||
|
||||
// —— 求最大子数组和(标准 Kadane) ——
|
||||
// 要么把 x 加到前面的子数组上,要么从 x 重新开始
|
||||
currMax = Math.max(currMax + x, x);
|
||||
maxSum = Math.max(maxSum, currMax);
|
||||
|
||||
// —— 求最小子数组和(相反 Kadane) ——
|
||||
currMin = Math.min(currMin + x, x);
|
||||
minSum = Math.min(minSum, currMin);
|
||||
}
|
||||
|
||||
// 如果所有元素都为负数,maxSum 会是最大的负数,
|
||||
// totalSum - minSum 会变成 0(等价于丢弃整个数组),不合法
|
||||
if (maxSum < 0) {
|
||||
return maxSum;
|
||||
}
|
||||
|
||||
// 否则比较非环形和环形两种情况
|
||||
return Math.max(maxSum, totalSum - minSum);
|
||||
}
|
||||
}
|
55
src/main/java/graph/FindOrder.java
Normal file
55
src/main/java/graph/FindOrder.java
Normal file
@ -0,0 +1,55 @@
|
||||
package graph;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
/**
|
||||
* 题目: 210. 课程表 II (findOrder)
|
||||
* 描述:现在你总共有 numCourses 门课需要选,记为 0 到 numCourses - 1。给你一个数组 prerequisites ,其中 prerequisites[i] = [ai, bi] ,表示在选修课程 ai 前 必须 先选修 bi 。
|
||||
* 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示:[0,1] 。
|
||||
* 返回你为了学完所有课程所安排的学习顺序。可能会有多个正确的顺序,你只要返回 任意一种 就可以了。如果不可能完成所有课程,返回 一个空数组 。
|
||||
*
|
||||
示例 1:
|
||||
输入:numCourses = 2, prerequisites = [[1,0]]
|
||||
输出:[0,1]
|
||||
解释:总共有 2 门课程。要学习课程 1,你需要先完成课程 0。因此,正确的课程顺序为 [0,1] 。
|
||||
|
||||
* 链接:https://leetcode.cn/problems/course-schedule-ii/
|
||||
|
||||
*/
|
||||
public class FindOrder {
|
||||
public int[] findOrder(int numCourses, int[][] prerequisites) {
|
||||
int[] indegree=new int[numCourses];
|
||||
int[] res=new int[numCourses];
|
||||
int index=0;
|
||||
// 构建图:graph.get(i) 存储课程 i 的后续课程
|
||||
List<List<Integer>> graph = new ArrayList<>();
|
||||
// 初始化图
|
||||
for (int i = 0; i < numCourses; i++) {
|
||||
graph.add(new ArrayList<>());
|
||||
}
|
||||
Queue<Integer>queue=new ArrayDeque<>();
|
||||
for (int[] prerequisite : prerequisites) {
|
||||
int course=prerequisite[0];
|
||||
int precourse=prerequisite[1];
|
||||
graph.get(precourse).add(course);
|
||||
indegree[course]++;
|
||||
}
|
||||
for (int i = 0; i < numCourses; i++) {
|
||||
if(indegree[i]==0)queue.offer(i);
|
||||
}
|
||||
while (!queue.isEmpty()){
|
||||
int cur=queue.poll();
|
||||
res[index++]=cur;
|
||||
List<Integer>tp=graph.get(cur);
|
||||
for (Integer course : tp) {
|
||||
indegree[course]--;
|
||||
if(indegree[course]==0) queue.offer(course);
|
||||
}
|
||||
}
|
||||
if(index==numCourses)return res;
|
||||
else return new int[0];
|
||||
}
|
||||
}
|
57
src/main/java/graph/LadderLength.java
Normal file
57
src/main/java/graph/LadderLength.java
Normal file
@ -0,0 +1,57 @@
|
||||
package graph;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 题目: 127. 单词接龙 (ladderLength)
|
||||
* 描述:字典 wordList 中从单词 beginWord 到 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> ... -> sk:
|
||||
*
|
||||
* 每一对相邻的单词只差一个字母。
|
||||
* 对于 1 <= i <= k 时,每个 si 都在 wordList 中。注意, beginWord 不需要在 wordList 中。
|
||||
* sk == endWord
|
||||
* 给你两个单词 beginWord 和 endWord 和一个字典 wordList ,返回 从 beginWord 到 endWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0 。
|
||||
*
|
||||
示例 1:
|
||||
输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
|
||||
输出:5
|
||||
解释:一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog", 返回它的长度 5。
|
||||
|
||||
* 链接:https://leetcode.cn/problems/word-ladder/
|
||||
|
||||
*/
|
||||
//和433. 最小基因变化雷同
|
||||
public class LadderLength {
|
||||
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
|
||||
Set<String>set=new HashSet<>(wordList);
|
||||
Set<String>visited=new HashSet<>();
|
||||
Queue<String> queue=new ArrayDeque<>();
|
||||
queue.add(beginWord);
|
||||
visited.add(beginWord);
|
||||
if(!set.contains(endWord))return 0;
|
||||
int steps=1;
|
||||
while (!queue.isEmpty()){
|
||||
int sz= queue.size();
|
||||
for (int i = 0; i < sz; i++) {
|
||||
String cur=queue.poll();
|
||||
if(cur.equals(endWord))
|
||||
return steps;
|
||||
char[] currArr = cur.toCharArray();
|
||||
for (int pos = 0; pos < currArr.length; pos++) {
|
||||
char old=currArr[pos];
|
||||
for (int j = 0; j < 26; j++) {
|
||||
char g= (char) ('a'+j);
|
||||
currArr[pos]=g;
|
||||
String next=new String(currArr);
|
||||
if(set.contains(next)&&!visited.contains(next)){
|
||||
visited.add(next);
|
||||
queue.offer(next);
|
||||
}
|
||||
}
|
||||
currArr[pos]=old;
|
||||
}
|
||||
}
|
||||
steps++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
100
src/main/java/graph/MinMutation.java
Normal file
100
src/main/java/graph/MinMutation.java
Normal file
@ -0,0 +1,100 @@
|
||||
package graph;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 题目: 433. 最小基因变化 (minMutation)
|
||||
* 描述:基因序列可以表示为一条由 8 个字符组成的字符串,其中每个字符都是 'A'、'C'、'G' 和 'T' 之一。
|
||||
* 假设我们需要调查从基因序列 start 变为 end 所发生的基因变化。一次基因变化就意味着这个基因序列中的一个字符发生了变化。
|
||||
* 例如,"AACCGGTT" --> "AACCGGTA" 就是一次基因变化。
|
||||
* 另有一个基因库 bank 记录了所有有效的基因变化,只有基因库中的基因才是有效的基因序列。(变化后的基因必须位于基因库 bank 中)
|
||||
* 给你两个基因序列 start 和 end ,以及一个基因库 bank ,请你找出并返回能够使 start 变化为 end 所需的最少变化次数。如果无法完成此基因变化,返回 -1 。
|
||||
* 注意:起始基因序列 start 默认是有效的,但是它并不一定会出现在基因库中。
|
||||
*
|
||||
示例 1:
|
||||
输入:start = "AACCGGTT", end = "AAACGGTA", bank = ["AACCGGTA","AACCGCTA","AAACGGTA"]
|
||||
输出:2
|
||||
|
||||
* 链接:https://leetcode.cn/problems/minimum-genetic-mutation/
|
||||
|
||||
*/
|
||||
//不会
|
||||
public class MinMutation {
|
||||
/**
|
||||
* 准备工作
|
||||
*
|
||||
* 将基因库 bank 中的有效基因串存入一个 Set<String> valid,用于 O(1) 检查。
|
||||
* 如果 endGene 不在 valid 中,说明无法达到目标,直接返回 –1。
|
||||
* BFS 初始化
|
||||
*
|
||||
* 使用队列 Queue<String> 存放当前层(当前步数)所有可达的基因串。
|
||||
* 另用一个 Set<String> visited 记录已经访问过的基因串,避免重复遍历。
|
||||
* 将起点 startGene 入队、标记已访问;将步数 steps 置 0。
|
||||
* 层次遍历
|
||||
*
|
||||
* 每次遍历一层时,取出当前队列大小 sz,表示这一层共有 sz 个节点要处理;
|
||||
* 对每个节点(基因串)进行:
|
||||
* 若它等于 endGene,则返回当前 steps。
|
||||
* 否则,尝试对这条基因串的 8 个位置,逐个替换为 'A' / 'C' / 'G' / 'T' 中另一种字符,生成所有 “相差 1 位” 的新基因串 next;
|
||||
* 如果 next 在 valid 且未被访问过,就将其入队并标记访问。
|
||||
* 步数递增
|
||||
*
|
||||
* 当前层的所有节点都处理完后,steps++,进入下一层。
|
||||
* 直到队列为空仍未找到 endGene,返回 –1。
|
||||
* @param startGene
|
||||
* @param endGene
|
||||
* @param bank
|
||||
* @return
|
||||
*/
|
||||
public int minMutation(String startGene, String endGene, String[] bank) {
|
||||
// 1. 将 bank 放入 Set,便于快速查验
|
||||
Set<String> valid = new HashSet<>(Arrays.asList(bank));
|
||||
// 如果目标不在 bank 中,无法达成
|
||||
if (!valid.contains(endGene)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 2. BFS 初始化
|
||||
char[] genes = new char[] {'A', 'C', 'G', 'T'};
|
||||
Queue<String> queue = new ArrayDeque<>();
|
||||
Set<String> visited = new HashSet<>();
|
||||
|
||||
queue.offer(startGene);
|
||||
visited.add(startGene);
|
||||
int steps = 0;
|
||||
|
||||
// 3. 开始层次遍历
|
||||
while (!queue.isEmpty()) {
|
||||
int sz = queue.size();
|
||||
// 处理当前层中的所有节点
|
||||
for (int i = 0; i < sz; i++) {
|
||||
String curr = queue.poll();
|
||||
// 找到目标,返回步数
|
||||
if (curr.equals(endGene)) {
|
||||
return steps;
|
||||
}
|
||||
// 生成所有一位变异的基因串
|
||||
char[] currArr = curr.toCharArray();
|
||||
for (int pos = 0; pos < currArr.length; pos++) {
|
||||
char old = currArr[pos];
|
||||
for (char g : genes) {
|
||||
if (g == old) continue; // 跳过相同字符
|
||||
currArr[pos] = g;
|
||||
String next = new String(currArr);
|
||||
// 只有在 bank 且未访问过,才入队
|
||||
if (valid.contains(next) && !visited.contains(next)) {
|
||||
queue.offer(next);
|
||||
visited.add(next);
|
||||
}
|
||||
}
|
||||
currArr[pos] = old; // 恢复现场,不然每个pos都变了
|
||||
}
|
||||
}
|
||||
// 当前层遍历完,步数+1
|
||||
steps++;
|
||||
}
|
||||
|
||||
// 队列空了也没找到,返回 -1
|
||||
return -1;
|
||||
}
|
||||
}
|
@ -1,7 +1,5 @@
|
||||
package graph;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 题目: 200. 岛屿数量 (numIslands)
|
||||
* 描述:给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。
|
||||
|
@ -12,47 +12,98 @@ package graph;
|
||||
|
||||
*/
|
||||
//没搞懂 学习一下
|
||||
|
||||
/**
|
||||
* 节点结构
|
||||
*
|
||||
* 每个 Trie 对象代表一棵子树的根节点,内部维护一个 children[26] 数组,对应 26 个字母。
|
||||
* isEnd 标识该节点是否是某个已插入单词的末尾。
|
||||
* 插入 (insert)
|
||||
* 从根节点出发,依次读取单词每个字符,计算索引 ch - 'a'。
|
||||
* 若对应子节点为空则新建,最后将游标节点标记为单词结尾。
|
||||
*
|
||||
* 查找完整单词 (search)
|
||||
* 调用内部方法 searchPrefix,找到单词走到的最后一个节点;
|
||||
* 再检查该节点的 isEnd,为 true 时说明完整单词存在。
|
||||
*
|
||||
* 前缀判断 (startsWith)
|
||||
* 仍用 searchPrefix 定位到最后一个节点;
|
||||
* 不需要检查 isEnd,只要节点不为 null 就说明有该前缀。
|
||||
*
|
||||
* 共用方法 (searchPrefix)
|
||||
* 将插入和查找里的公共逻辑抽取出来:遍历路径、空指针检查、节点推进。
|
||||
*/
|
||||
//https://leetcode.cn/problems/implement-trie-prefix-tree/solutions/98390/trie-tree-de-shi-xian-gua-he-chu-xue-zhe-by-huwt/?envType=study-plan-v2&envId=top-interview-150
|
||||
class Trie {
|
||||
// children 数组保存当前节点的所有子节点,索引 0-25 分别对应 'a'-'z'
|
||||
private Trie[] children;
|
||||
// isEnd 标志用于标识当前节点是否为一个完整单词的结尾
|
||||
private boolean isEnd;
|
||||
|
||||
/**
|
||||
* Initialize your data structure here.
|
||||
*/
|
||||
public Trie() {
|
||||
children = new Trie[26]; //这行代码只是 创建了一个长度为 26 的数组,对应 a ~ z。但是!数组里的元素初始都是 null,只有当需要用到某个字符时,才会创建对应的 Trie 节点。
|
||||
// 初始化 children 数组,初始时所有子节点都为 null
|
||||
children = new Trie[26];
|
||||
// 初始化单词结尾标志为 false
|
||||
isEnd = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a word into the trie.
|
||||
*/
|
||||
public void insert(String word) {
|
||||
Trie node = this;
|
||||
Trie node = this; // 从根节点开始
|
||||
for (int i = 0; i < word.length(); i++) {
|
||||
char ch = word.charAt(i);
|
||||
int index = ch - 'a';
|
||||
char ch = word.charAt(i); // 当前字符
|
||||
int index = ch - 'a'; // 计算在 children 数组中的索引
|
||||
// 如果对应字符的子节点不存在,则新建一个节点
|
||||
if (node.children[index] == null) {
|
||||
node.children[index] = new Trie();
|
||||
}
|
||||
// 移动到子节点,继续处理下一个字符
|
||||
node = node.children[index];
|
||||
}
|
||||
// 遍历完所有字符后,将当前节点标记为单词结尾
|
||||
node.isEnd = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the word is in the trie.
|
||||
*/
|
||||
public boolean search(String word) {
|
||||
// 尝试查找完整单词对应的节点
|
||||
Trie node = searchPrefix(word);
|
||||
// 只有节点不为 null 且 isEnd 为 true 才说明单词存在
|
||||
return node != null && node.isEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there is any word in the trie that starts with the given prefix.
|
||||
*/
|
||||
public boolean startsWith(String prefix) {
|
||||
// 只要能找到 prefix 对应的最后一个节点,就说明存在该前缀
|
||||
return searchPrefix(prefix) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找给定字符串对应的最后一个节点,若路径中断则返回 null。
|
||||
*/
|
||||
private Trie searchPrefix(String prefix) {
|
||||
Trie node = this;
|
||||
Trie node = this; // 从根节点开始
|
||||
for (int i = 0; i < prefix.length(); i++) {
|
||||
char ch = prefix.charAt(i);
|
||||
int index = ch - 'a';
|
||||
int index = ch - 'a'; // 计算字符索引
|
||||
// 若对应子节点不存在,则前缀/单词不在 Trie 中
|
||||
if (node.children[index] == null) {
|
||||
return null;
|
||||
}
|
||||
// 移动到子节点,继续检查下一个字符
|
||||
node = node.children[index];
|
||||
}
|
||||
// 成功遍历所有字符,返回最后停留的节点
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
|
87
src/main/java/tree/WordDictionary.java
Normal file
87
src/main/java/tree/WordDictionary.java
Normal file
@ -0,0 +1,87 @@
|
||||
package tree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 题目: 添加与搜索单词 - 数据结构设计 (WordDictionary)
|
||||
* 描述:请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。
|
||||
*
|
||||
* 实现词典类 WordDictionary :
|
||||
*
|
||||
* WordDictionary() 初始化词典对象
|
||||
* void addWord(word) 将 word 添加到数据结构中,之后可以对它进行匹配
|
||||
* bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 true ;否则,返回 false 。word 中可能包含一些 '.' ,每个 . 都可以表示任何一个字母。
|
||||
*
|
||||
示例 1:
|
||||
输入:
|
||||
["WordDictionary","addWord","addWord","addWord","search","search","search","search"]
|
||||
[[],["bad"],["dad"],["mad"],["pad"],["bad"],[".ad"],["b.."]]
|
||||
输出:
|
||||
[null,null,null,null,false,true,true,true]
|
||||
|
||||
解释:
|
||||
WordDictionary wordDictionary = new WordDictionary();
|
||||
wordDictionary.addWord("bad");
|
||||
wordDictionary.addWord("dad");
|
||||
wordDictionary.addWord("mad");
|
||||
wordDictionary.search("pad"); // 返回 False
|
||||
wordDictionary.search("bad"); // 返回 True
|
||||
wordDictionary.search(".ad"); // 返回 True
|
||||
wordDictionary.search("b.."); // 返回 True
|
||||
|
||||
* 链接:https://leetcode.cn/problems/design-add-and-search-words-data-structure/
|
||||
|
||||
*/
|
||||
public class WordDictionary {
|
||||
// Trie 树的节点
|
||||
private WordDictionary[] children;
|
||||
private boolean isEnd;
|
||||
|
||||
public WordDictionary() {
|
||||
children = new WordDictionary[26]; // 存储 26 个字母的子节点
|
||||
isEnd = false; // 默认节点不是单词的结尾
|
||||
}
|
||||
|
||||
// 添加单词
|
||||
public void addWord(String word) {
|
||||
WordDictionary node = this;
|
||||
for (int i = 0; i < word.length(); i++) {
|
||||
int index = word.charAt(i) - 'a'; // 计算字符的索引
|
||||
if (node.children[index] == null) {
|
||||
node.children[index] = new WordDictionary(); // 如果子节点不存在,就创建一个新节点
|
||||
}
|
||||
node = node.children[index]; // 移动到当前字符的子节点
|
||||
}
|
||||
node.isEnd = true; // 单词的结尾标志
|
||||
}
|
||||
|
||||
// 搜索单词,支持通配符 "."
|
||||
public boolean search(String word) {
|
||||
return searchInNode(word, this); // 从根节点开始搜索
|
||||
}
|
||||
|
||||
// 辅助方法,递归遍历 Trie
|
||||
private boolean searchInNode(String word, WordDictionary node) {
|
||||
if (word.length() == 0) {
|
||||
return node.isEnd; // 如果单词已遍历完,检查当前节点是否是一个完整单词
|
||||
}
|
||||
|
||||
char firstChar = word.charAt(0);
|
||||
if (firstChar == '.') {
|
||||
// 如果是通配符 '.', 检查每个子节点
|
||||
for (int i = 0; i < 26; i++) {
|
||||
if (node.children[i] != null && searchInNode(word.substring(1), node.children[i])) { //word.substring(1):从 word 字符串的第二个字符
|
||||
return true; // 如果任意一个子节点能匹配,返回 true
|
||||
}
|
||||
}
|
||||
return false; // 如果所有子节点都无法匹配,返回 false
|
||||
} else {
|
||||
int index = firstChar - 'a'; // 计算字母的索引
|
||||
if (node.children[index] == null) {
|
||||
return false; // 如果当前字符对应的子节点为空,返回 false
|
||||
}
|
||||
return searchInNode(word.substring(1), node.children[index]); // 向下递归检查
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user