从具体案列,数据结构基础知识,常用算法、高频真题演练和面试技巧五个方面;
复杂度–衡量程序运行的效率的度量。
数据(组织)结构决定着算法和代码结构。对于常用的增删改查操作:Eg: 数组查改简便但增删却很麻烦,而链表相反。这就对应着时间复杂度不同。
计算机通过一个个程序去执行计算任务,也就是对输入数据进行加工处理,并最终得到结果的过程。每个程序都是由代码构成的,编写代码的核心就是要完成计算。但对于同一个计算任务,不同计算方法得到结果的过程复杂程度不一样。
复杂度脑海里是一种意识,只需要知道是什么级别,而不需要具体。
假传万卷书,真传一案例。
Case1:假设有任意多张面额为2元,3元,7元的货币,现用他们凑出100元,总共有多少种可能性?
// 起点: 暴力法--穷举法
public void s2_1(){
int count =0;
for(int i=0;i<=100/7;i++){
for(int j = 0;j<=100/3;j++){
for(int k=0;l<=100/2);k++){
if(i*7+j*3+k*2=100){
count+=1;
}
}
}
}
system.out.println(count);
};
分析:时间复杂度O(n^3),代码中最内层的for循环是多余的,当确定用i张7元和j张3元的,只需判断能否使用2元来凑就可以了;
// 思路一:将代码中的无效计算去除
public void s2_1(){
int count =0;
for(int i=0;i<=100/7;i++){
for(int j = 0;j<=100/3;j++){
if((100-i*7-j*3>=0)&&((100-i*7-j*3)%2==0)){
count++;
}
}
}
system.out.println(count);
};
Case2: 查找一个数组中,出现次数最多那个元素的数值。例如数组a[7]=[1,2,3,4,5,5,6]中,5出现次数最多:2次;
// 采用两层循环:第一层循环:对数组每个元素遍历;第二层循环:对一层遍历的数字,去遍历计算其出现的次数
public void s2_1(){
int a[]=[1,2,3,4,5,5,6];
int val_max=-1;
int time_max=0;
int time_tmp=0;
for(int i=0;itime_max){
time_max=time_tmp;
val_max=a[i];
}
}
}
system.out.println(val_max);
}
分析:采用两层for循环,时间复杂度O(n^2)。在代码中,没有冗余的无效计算。再去优化,考虑常用算法来替代;最后思路考虑:数据结构来时空转化;
// 通过一次循环确定:在一次遍历的过程中同步不记录下每个元素出现的次数,然后再通过查找次数最大的元素。
// 定义一个结构的K-V字典,用来存放 元素-出现次数的K-V关系字典。
public void s2_2(){
int a[]={1,2,3,4,5,5,6};
Map d=new HashMap<>();
for(int i =0;itime_max){
time_max=d.get(key);
val_max=key;
}
}
}
system.out.println(val_max);
}
分析:并列for循环,O(n);通过采用高效但一般复杂的数据结构,完成时空转移,降低复杂度。
降低复杂度,代码优化的步骤;
学习来源: 文字教程–拉钩教育