先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
正文
arr.append(“%20”);
}else{
//不是空格就之间加到arr末尾
arr.append(s.charAt(i));
}
}
//返回String形式
return arr.toString();
}
}
🍐4.翻转字符串里的单词(中等)
给你一个字符串 s ,逐个翻转字符串中的所有 单词 。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
请你返回一个翻转 s 中单词顺序并用单个空格相连的字符串。
说明:
输入字符串 s 可以在前面、后面或者单词间包含多余的空格。
翻转后单词间应当仅用一个空格分隔。
翻转后的字符串中不应包含额外的空格。
题目链接:翻转字符串里的单词
题目分析:这道题在字符串里算是较有难度的一题,因为它几乎考察了所有的字符串处理操作,想要效率高的完成,还是比较难的,即使是用API,很多人也无从下手,但是这也让我们了解了更多API的使用操作,是一道非常好的题。下面我为大家讲解多种方法以及它们的效率如何。
❗️考点解析:1.如何修剪掉两端空格
2.如何把单词反转过来
3.如何跳过中间连续的空格
方法1:双指针遍历倒插(重点掌握的方法)
首先我们把题目给的String转换为char[],还要有一个StringBuilder接收答案。通过从指针从头尾开始遍历,如果指的值为空格,均往中间移动,直到不为空格,这样就剪掉了首尾空格。因为要单词反转,所以从后面的right开始寻找单词,从right的位置,用一个index指针往左移动,找到为空格的位置停止,然后将index+1倒right的位置的单词遍历放入到StringBuilder。接着index继续移动找到不为空格的位置,然后把right更新过来,后面接着同样的操作知道完成数组的遍历得到答案。其实全程除了除去首尾空白,left都没动过,right也是靠index来更新,主要是index的移动。
由于思路光用语言难以表达,为大家找到一篇优质图解,建议认真观看一下——双指针图解
时间复杂度O(n):n为s的长度,只遍历了一次
空间复杂度O(n):主要用来存储字符串,因语言而定,字符串可变的语言空间复杂度可为O(1)
class Solution {
public String reverseWords(String s) {
//转换为char数组
char[] arr = s.toCharArray();
int left = 0;
int right = arr.length-1;
//用来接收答案
StringBuilder sb = new StringBuilder();
//去掉空格
while(arr[left]==’ ') left++;
while(arr[right] == ’ ') right–;
//注意循环结束条件
while(left <= right){
//index从right开始出发
int index = right;
//找到为空的地方停下来,这里要注意也得大于等于left,不然在走到最左边可能会数组越界
while(index >= left && arr[index] != ’ ’ ) index–;
//注意此时index是指向空格的,从inde+1到right一个个字符加入到StringBuilder中
for(int i = index+1 ; i <= right ; i++ ) sb.append( arr[i] );
//因为中间的单词之间需要加空格,所以index>left时,说明还在中间,我们补一个空格
if(index > left) sb.append(’ ');
//然后我们继续移动index找到下一个单词的,这时也要保证index>=left,原理同上
while( index >= left && arr[index]==’ ’ ) index–;
//然后更新right到index
right = index;
}
return sb.toString();
}
}
方法2:API大法(虽然复杂度差不多,但其实效率比双指针低)
时间复杂度:O(n),其中 nn 为输入字符串的长度。
空间复杂度:O(n)O(n),用来存储字符串分割之后的结果
上面我们讲了这道题的考点解析,如果我们都能够用API来完成这些需求,那么代码就会很简单,前提是大家要会使用和了解这些API。
官方题解的API:
class Solution {
public String reverseWords(String s) {
// 除去开头和末尾的空白字符
s = s.trim();
// 正则匹配连续的空白字符作为分隔符分割
List wordList = Arrays.asList(s.split(“\s+”));
//Collections带的reverse方法可以之间反转,但需要传入一个List
Collections.reverse(wordList);
//String.join方法很冷门,它可以在第二个参数的两两元素之间插入第一个参数
return String.join(" ", wordList);
}
}
我写的API法:
class Solution {
public String reverseWords(String s) {
//去掉首尾空格的API,需要会用
String c=s.trim();
//以连续的空格为切割符,这里涉及到正则表达式
//ps:split的使用很广泛,请一定要学会
String[] arr=c.split(“\s+”);
StringBuilder a=new StringBuilder();
//从
for(int i=arr.length-1;i>=0;i–){
//从尾向头一个个单词插入
//每次插入后补一个空格
a.append(arr[i]+" ");
}
//最后一个单词后面不用空格,删掉最后一个
a.deleteCharAt(a.length()-1);
return a.toString();
}
}
🍑5.左旋转字符串
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
题目链接:左旋转字符串
题目分析:题目的要求很简单,无非就是将前n个字符移到后面即可,我们可以用StringBuilder或者StringBuffer先接收后面的字符,再接收前n个字符。
方法1:StringBuffer接收
时间复杂度O(n):n为s的长度,遍历的耗时
空间复杂度O(n):主要是StringBuffer的消耗
PS:若面试要求只能用String,这里也可用String,只不过Python和Java中的String不可变,每次都要新建一个字符串且拼接的效率低,每次都要申请内存,当数据量大时效率低,且申请内存高。
class Solution {
public String reverseLeftWords(String s, int n) {
StringBuffer a=new StringBuffer();
for(int i=n;i<s.length();i++){
a.append(s.charAt(i));
}
for(int i=0;i<n;i++){
a.append(s.charAt(i));
}
return a.toString();
}
}
方法2:String的substring(效率高需掌握,常用API)
时间复杂度O(n):n为s的长度
空间复杂度O(n):n为s的长度
class Solution {
public String reverseLeftWords(String s, int n) {
return s.substring(n, s.length()) + s.substring(0, n);
}
}
🍈6.最后一个单词的长度
====================
给你一个字符串
s
,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中最后一个单词的长度。
单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。
分析:这道题可以看作为第四道题的子题,我们可以考虑同样的做法,反向遍历用指针去找到最后一个字母的起始索引和结尾索引,从而求得长度。
方法:反向遍历
时间复杂度O(n):n为字符串的长度,最多反向遍历整个字符串一遍
空间复杂度O(1):
class Solution {
public int lengthOfLastWord(String s) {
//从末尾开始遍历
int index=s.length()-1;
//结尾有空格有往左移动
while(s.charAt(index)==’ '){
index–;
}
//此时index指向最后一个单词的最后一个字母,用a记录此时的位置
int a=index;
//index继续移动,保证index>0
//这里要注意index指向的是最后一个单词前面的空格
while(index>=0&&s.charAt(index)!=’ '){
index–;
}
//相减获得长度
return a-index;
}
}
🌽7.字符串中的第一个唯一字符
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
题目分析:看到这个题目首先应该想到String的indexOf和lastindexOf两个API方法,其次应该想到暴力遍历的方法。效率高的方法,应该想到利用哈希,这里我们不采用map而采用数组来映射,因为数组也是哈希映射的一种体现。什么?你说你还不太会哈希或者不懂数组体现哈希?那你快看看这套哈希专题——【哈希系列】舍友担心期末考睡不着,我连夜准备了这套哈希全套专题
方法1:利用String的****indexOf和lastIndexOf
时间复杂度O(n^2):涉及到API的源码,内部也是循环实现,这个方法复杂度较高
空间复杂度O(1)
class Solution {
public int firstUniqChar(String s) {
for(int i=0;i<s.length();i++){
//indexOf获得某个元素从头遍历第一次出现的位置
//lastIndexOf获得某个元素从尾到头遍历第一次出现的位置
//如果相等说明这个字母就一个
if(s.indexOf(s.charAt(i))==s.lastIndexOf(s.charAt(i))){
return i;
}
}
//没找到返回-1
return -1;
}
}
方法2: 利用数组哈希映射
时间复杂度O(n):进行两次遍历,这里也可用哈希表来做,只不过使用数组的效率更好,推荐大家两种都要尝试。
空间复杂度O(1):常数长度的数组消耗,看为O(1)的复杂度消耗
class Solution {
public int firstUniqChar(String s) {
//统计26个字母出现的频率
int[] arr=new int[26];
//遍历一次数组统计出现的每个字母出现的次数
for(int i=0;i<s.length();i++){
arr[s.charAt(i)-‘a’]++;
写在最后
可能有人会问我为什么愿意去花时间帮助大家实现求职梦想,因为我一直坚信时间是可以复制的。我牺牲了自己的大概十个小时写了这片文章,换来的是成千上万的求职者节约几天甚至几周时间浪费在无用的资源上。
上面的这些(算法与数据结构)+(Java多线程学习手册)+(计算机网络顶级教程)等学习资源
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
=0;i<s.length();i++){
arr[s.charAt(i)-‘a’]++;
写在最后
可能有人会问我为什么愿意去花时间帮助大家实现求职梦想,因为我一直坚信时间是可以复制的。我牺牲了自己的大概十个小时写了这片文章,换来的是成千上万的求职者节约几天甚至几周时间浪费在无用的资源上。
[外链图片转存中…(img-GElhATjU-1713666861094)]
[外链图片转存中…(img-v6y1dJWy-1713666861094)]
上面的这些(算法与数据结构)+(Java多线程学习手册)+(计算机网络顶级教程)等学习资源
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-ORBrC6OW-1713666861095)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!