总结
总体来说,如果你想转行从事程序员的工作,Java开发一定可以作为你的第一选择。但是不管你选择什么编程语言,提升自己的硬件实力才是拿高薪的唯一手段。
如果你以这份学习路线来学习,你会有一个比较系统化的知识网络,也不至于把知识学习得很零散。我个人是完全不建议刚开始就看《Java编程思想》、《Java核心技术》这些书籍,看完你肯定会放弃学习。建议可以看一些视频来学习,当自己能上手再买这些书看又是非常有收获的事了。
循环语句根据循环的次数的变化而分为O(1),O(N),上面说过O(1)那么O(n)就是循环的次数随着题目或者问题的改变而改变的,就属于O(n)
而判断整个程序时间复杂度的方法为,以时间复杂度最高的为主:也就是说,就算你赋值了1000000个变量,而循环结果是随时间变化的,那么你的程序的时间复杂度为:O(n)
因为随着循环次数的增加,也就是n->无穷大,你的变量数目,也会相对于n来说越来越小。
所以可以忽略不计,为O(1)*O(n)==O(n)
常见的时间复杂度:O(1),O(logn),O(n),O(nlogn),O(n*2),O(2**n)O(n!)
按照从小到大的顺序排列
2. 空间复杂度O()
空间复杂度也具有相同的概念,只是有些地方变得不太一样了
如果说时间还能掐秒计算时间,那么占用空间就没那么好计算了,难不成,你去看看代码多少航,行多的占用内存就大吗?这也不是,有的代码很少,但是需要占用的内存多,有的代码看着很多,但是占用内存很小
空间复杂度是想对占用空间,比如说,你的程序创建100个变量接收了100个数字,字符串,在空间复杂度里面属于O(1),而你创建一个数组,哈希表,栈等就是O(n)
三、刷题小结
自从开始刷力扣,也有些许日子了,从一开始的每日一题,到每日两题,再到学习学到无聊的时候就去刷题,也算是经历了一番蜕变。
从一开始的什么都不懂,做题全靠暴力破解,但现在掌握了几个方法。
也了解了一些关于数据结构与算法的小知识
学习新知识固然重要,但是也需要总结之前的知识,毕竟温故而知新嘛
1. 二分法
二分查找法是一种算法
他经常用在:
给定一个升序的数组/列表和一个目标值,尽可能快的查找其中的目标值
若存在,返回目标值得索引
若不存在,返回-1
这样的场景
相比于直接遍历整个数组,使用二分法无疑会让我们的程序效率更高!
因为是升序的,所以我们可以以数组中间的元素为中线,将数组分为左右两个数组
python代码展示:
target = 7 # 给一个目标值
start = 0 # 用于计算中间值,和后面陆续的将数组划分为两个数组
end = len(li)-1 # 用于计算中间值,记录列表最后值的索引
li = [1, 2, 3, 4, 5, 6 ,7, 8, 9, 10]
while start<end:
# 记录一个循环
mid = (start+n)//2 # 值为4
"""
一个升序数组/列表
以中间mid(//是保持中间值为整数)为界限
看似分成两个数组
li\_left = [1, 2, 3 ,4, 5]
li\_right = [6, 7, 8, 9, 10]
"""
if target>li[mid]:
# 如果目标值比中间值大,就说名目标值(7)在右边的列表
start = mid+1 # 让start变成右边列表的第一个元素的索引
# 抛弃左边的列表不要,只看右边的列表li\_right = [6, 7, 8, 9, 10]
else:
# 如果目标值小于等于中间值,就说明目标值在左边的列表
end = mid # 让n变成左边列表的最大值的索引
# 抛弃右边的列表不要,只看左边的列表
print("mid的值就是目标值的索引:", mid)
# 运行结果为6
Java代码:
public class Test{
public static void main(String[] args){
int[] aa = new int[]{1, 2, 3, 4, 5, 6 ,7, 8, 9, 10};
int target = 7; // 给一个目标值,查找目标值是否在数组中
int start = 0; // 用于计算中间值,和后面陆续的将数组划分为两个数组
int mid = 0; // 设置中间值遍历
int end = aa.length; // 用于计算中间值,记录列表最后值的索引
while(start<end){ // 设置循环条件,当头指针小于尾指针时终止循环
mid = (start+end)/2;
/\*
一个升序数组/列表
以中间mid(//是保持中间值为整数)为界限
看似分成两个数组
左边是: [1, 2, 3 ,4, 5]
右边是: [6, 7, 8, 9, 10]
\*/
if (target>aa[mid]) start = mid+1; // 如果目标值比中间值大,就说名目标值(7)在右边的列表,让start变成右边列表的第一个元素的索引
else end = mid; // 如果目标值小于等于中间值,就说明目标值在左边的列表,让end编程左边列表的尾部
}
System.out.println("mid的值就是目标值在数组中的索引:"+mid);
}
}
// 运行结果为6
随着循环的进行,列表会越来越小,最后只剩目标值,然后最小值的索引就是我们需要的值
二分法时间复杂度分析:O(logn) 每次循环使数组长度减半,因此又被称为折半查找法
直接遍历整个数组(暴力解法)时间复杂度分析:O(n)
2. 双指针法
在我们的二分法中就是用了双指针的方法,起始时一个指针指向数组的头部,一个指针指向数组的尾部,使用这种方法会让我们对数组的操作更加流畅一些。
双指针法常常是用在:
查找某些元素时
力扣的第一道题就是一个经典的双指针优化程序的题目
给你一个目标值和一个有序数组
找出数组中和为目标值的元素
返回她们的下标
元素不能与自己相加
正常的做法是进行嵌套循环,挨个查找,这样的时间复杂度为:O(n*2)
而如果使用双指针的方法,结合二分法就能使时间复杂度降低到:O(logn)
遍历的方法就相当于一个人在找东西,双指针的方法就好像是两个人在找东西
打个例子:
我有一块种着10棵树的地
有人告诉我,你有一棵树需要浇水了
如果只有我自己(正常遍历)
并且我不需要跑到树前面观察才能判断我的树是否需要浇水
我只能一棵一棵的找,然后判断
而如果我有一个助手(双指针)
我就可以缩短排查的时间
java:
public class Shuzu {
public static void main(String[] args) {
int target = 7;
int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9};
System.out.println(ArrD(7,arr)+"\n"+ArrS(target,arr));
}
static int ArrD(int target, int[] arr) {
// 单指针
for (int i = 0; i < arr.length; i++) {
if (arr[i] == target) return i;
}
return -1;
}
static int ArrS(int target, int[] arr){
// 双指针
int end = arr.length-1;
int start = 0;
while (start<end){
if (arr[start]==target) return start;
if (arr[end]==target) return end;
start++;
end--;
}
return -1;
}
}
py:
def ArrD(target, arr):
# 单指针
for i in range(len(arr)):
if arr[i]target: return i
return -1;
def ArrS(target, arr):
# 双指针
start = 0
end = len(arr)-1
while start<end:
if arr[start]==target: return start
if arr[end]==target: return end
start+=1
end-=1
return end
target = 7
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(ArrD(target, arr), "\n", ArrS(target, arr))
3. 递归
递归与其说是一种算法,不如说是一种思想。
它更类似于我们高中数学学过的数列的递推推导式:A(n) = A(n-1)+5 首项为1
让你通过这个式子计算第n项的值的话
你高中会使用它推导出一个通项公式,再将n代入求解
但是再计算机眼里就不用这么麻烦
你只需要每次调用这个公式,然后计算出值就好
在编程语言里就是 :定义一个函数,调用自身,返回结果就是递归
就相当于计算机帮你从1开始执行了很多遍的A(n) = A(n-1)+5
无限套娃?不不不,他还是有个限度的,没法无限,哈哈哈
比如需要求A(5),那么就是:
A(5) = A(4)+5
A(4) = A(3)+5
A(3) = A(2)+5
A(2) = A(1)+5
A(1) = 3
A(5) = 3+5+5+5+5=23
代码实现:
java代码:
public class Digui {
public static void main(String[] args) {
int sum = Shu(5);
System.out.println(sum);
}
static int Shu(int n){
if (n<=1) return 3;
else return Shu(n-1)+5;
}
}
py代码:
def Shu(n:int)->int:
if n<=1: return 3
else: return Shu(n-1)+5
print(Shu(5))
最后的计算结果是23
4. 数组
什么是数组?数组就是存储多个相同数据的集合,他们的内存地址是相邻的,所以可以通过数组取值。
这么说,是不是有点不好理解,那么这样呢?
我有一颗白菜,手拿着就能回家,那如果是十几颗呢?
我就可以用麻袋!麻袋!装进去,带回家!是的你要存的数据就是白菜,而这个数组就是你要用的麻袋~~~~~
麻袋中的白菜怎么拿出来我需要用的呢?
下标,数组中的下标是以0开始的,什么是下标,就是你从0开始查,查到某个你要的数据,查到几,下标就是几,就相当于,我在装白菜的时候,说“这是第0个白菜,这是第1个白菜…”,而他们也能听懂(别管他们能不能听懂,我说能就能,哈哈~~),等我需要哪一颗白菜的时候,喊一声,他就自己跳出来了
当然我们的数组一般存储的数据比较多,而计算机又不和人一样能够直接看到数组的全部元素,他只记得里面第一颗白菜的样子,所以我们在查找某个元素,但是又不知道他在哪里的时候,只能通过遍历的手段来获取了
遍历每一棵白菜,将他与我们需要找的白菜对比没如果是就不找了,如果不是就继续找。
具体的代码形式我就不多说了,这个都是知道的。
5. 字符串
最后
如果觉得本文对你有帮助的话,不妨给我点个赞,关注一下吧!
棵白菜,将他与我们需要找的白菜对比没如果是就不找了,如果不是就继续找。
具体的代码形式我就不多说了,这个都是知道的。
5. 字符串
最后
如果觉得本文对你有帮助的话,不妨给我点个赞,关注一下吧!
[外链图片转存中…(img-qkHI9MqV-1715273366854)]
[外链图片转存中…(img-JyZjQ2qg-1715273366855)]