先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
正文
Trie
,又称前缀树或字典树,是一棵有根树,其每个节点包含以下字段:
- 指向子节点的指针数组
children
。对于本题而言,数组长度为26
,即小写英文字母的数量。此时children[0]
对应小写字母a
,children[1]
对应小写字母b
,…,children[25]
对应小写字母z
。
- 布尔字段
isEnd
,表示该节点是否为字符串的结尾。
我习惯用
next
替代children
,因为比较好写吧,这题相当于介绍前缀树,所以代码也很简单,不懂的可以先百度前缀树,了解了再来看,无非就是把二叉树替换成26
叉树,然后一个bool
判断是否到达结尾,然后掌握插入和查询方法。
class Trie {
private:
// 前缀树, 相当于26叉树
vector<Trie*> next;
// 判断是否为单词终点
bool isWrod;
// 因为search,startsWith方法都需要查询,所以提取出查询方法
// 直接返回查询最后的点
Trie* searchPrefix(string prefix) {
Trie* node = this;
for(char ch : prefix) {
int index = ch - ‘a’;
if(node->next[index] != nullptr) {
node = node->next[index];
}else {
return nullptr;
}
}
return node;
}
public:
Trie():next(26),isWrod(false) {}
void insert(string word) {
int count = 0;
// 指向当前类,每个类都有26个分支
Trie* node = this;
for(char ch : word) {
int index = ch - ‘a’;
if(node->next[index] == nullptr) {
// 创建父类节点的index节点,此时index也有26个分支
node->next[index] = new Trie();
}
// 将父类指向index节点
node = node->next[index];
}
// 创建完当前node指向最后一个单词,设为单词终点
node->isWrod = true;
}
// 不为空 and 最后一个点的isWrod为true 代表word存在
bool search(string word) {
Trie* node = this->searchPrefix(word);
return node != nullptr && node->isWrod;
}
// 不为空即查到了前缀
bool startsWith(string prefix) {
Trie* node = this->searchPrefix(prefix);
return node != nullptr;
}
};
=========================================================================
题目:
在英语中,有一个叫做 词根(
root
) 的概念,它可以跟着其他一些词组成另一个较长的单词——我们称这个词为 继承词(successor
)。例如,词根an
,跟随着单词other
(其他),可以形成新的单词another
(另一个)。
现在,给定一个由许多词根组成的词典和一个句子,需要将句子中的所有继承词用词根替换掉。如果继承词有许多可以形成它的词根,则用最短的词根替换它。
需要输出替换之后的句子。
示例:
输入:dictionary = [“cat”,“bat”,“rat”], sentence = “the cattle was rattled by the battery”
输出:“the cat was rat by the bat”
提示:
-
1 <= dictionary.length <= 1000
-
1 <= dictionary[i].length <= 100
-
dictionary[i]
仅由小写字母组成。 -
1 <= sentence.length <= 10^6
-
sentence
仅由小写字母和空格组成。 -
sentence
中单词的总量在范围[1, 1000]
内。 -
sentence
中每个单词的长度在范围[1, 1000]
内。 -
sentence
中单词之间由一个空格隔开。 -
sentence
没有前导或尾随空格。
思路:
- 将词根加入到前缀树中,
insert
方法跟上一题一样
- 分割字符串,将单词保存到数组中
- 处理字符串,就是找到词根就截取单词的词根部分,否则直接添加单词
`prefixLen`方法跟上题查询方法很像,本来查到结尾返回`true`,现在返回词根长度,查不到结尾就返回`0`,方便判断是否查到词根
class Trie {
private:
bool isWord;
vector<Trie*> next;
public:
Trie():next(26,nullptr),isWord(false){};
// 跟上一题一样
void insert(const string& word) {
Trie* node = this;
for(char ch : word) {
int index = ch - ‘a’;
if(node->next[index] == nullptr) {
node->next[index] = new Trie();
}
node = node->next[index];
}
node->isWord = true;
}
// 相对于上一题的search稍作修改
int prefixLen(const string& word) {
Trie* node = this;
// 返回前缀的长度
int len = 0;
for(char ch : word) {
int index = ch - ‘a’;
// 没有这个前缀
if(node->next[index] == nullptr) {
return 0;
}
node = node->next[index];
len++;
// 找到这个前缀并返回这个前缀的长度
if(node->isWord)
return len;
}
return 0;
}
};
class Solution {
public:
string replaceWords(vector& dictionary, string sentence) {
Trie* root = new Trie();
// 将词根加入前缀树
for(auto& word : dictionary) {
root->insert(word);
}
// 分割字符串
vector words{“”};
for(char ch : sentence) {
if(ch == ’ ') {
words.push_back(“”);
}else {
words.back().push_back(ch);
}
}
// 处理字符串
string res;
for(auto& word : words) {
int len = root->prefixLen(word);
// 没找到直接添加
if(len == 0){
res += word + " ";
}else {
// 找到前缀只添加前缀部分
res += word.substr(0, len) + " ";
}
}
res.pop_back();
return res;
}
};
==========================================================================
题目:
设计一个使用单词列表进行初始化的数据结构,单词列表中的单词 互不相同 。 如果给出一个单词,请判定能否只将这个单词中一个字母换成另一个字母,使得所形成的新单词存在于已构建的神奇字典中。
实现
MagicDictionary
类:
MagicDictionary()
初始化对象
void buildDict(String[] dictionary)
使用字符串数组dictionary
设定该数据结构,dictionary
中的字符串互不相同
bool search(String searchWord)
给定一个字符串searchWord
,判定能否只将字符串中 一个 字母换成另一个字母,使得所形成
示例:
输入
inputs = [“MagicDictionary”, “buildDict”, “search”, “search”, “search”, “search”]
inputs = [[], [[“hello”, “leetcode”]], [“hello”], [“hhllo”], [“hell”], [“leetcoded”]]
输出
[null, null, false, true, false, false]
解释
MagicDictionary magicDictionary = new MagicDictionary();
magicDictionary.buildDict([“hello”, “leetcode”]);
magicDictionary.search(“hello”); // 返回 False
magicDictionary.search(“hhllo”); // 将第二个 ‘h’ 替换为 ‘e’ 可以匹配 “hello” ,所以返回 True
magicDictionary.search(“hell”); // 返回 False
magicDictionary.search(“leetcoded”); // 返回 False
提示:
-
1 <= dictionary.length <= 100
-
1 <= dictionary[i].length <= 100
-
dictionary[i]
仅由小写英文字母组成 -
dictionary
中的所有字符串 互不相同 -
1 <= searchWord.length <= 100
总结
其他的内容都可以按照路线图里面整理出来的知识点逐一去熟悉,学习,消化,不建议你去看书学习,最好是多看一些视频,把不懂地方反复看,学习了一节视频内容第二天一定要去复习,并总结成思维导图,形成树状知识网络结构,方便日后复习。
这里还有一份很不错的《Java基础核心总结笔记》,特意跟大家分享出来
目录:
部分内容截图:
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
习。
这里还有一份很不错的《Java基础核心总结笔记》,特意跟大家分享出来
目录:
[外链图片转存中…(img-SvTx30jw-1713637607919)]
部分内容截图:
[外链图片转存中…(img-Q0VbZHPW-1713637607920)]
[外链图片转存中…(img-4oycKwB4-1713637607921)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-CUFzzzx1-1713637607921)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!