学习资源:拉勾教育
降低复杂度的三个步骤
- 第一步,
暴力解法
:在没有任何时间、空间约束下,完成代码任务的开发 - 第二步,
无效操作处理
:将代码中的无效计算、无效存储剔除,降低时间或空间复杂度- 学会掌握递归、二分法、排序算法、动态规划等常用的算法思维
- 第三步,
时空转换
:设计合理数据结构,完成时间复杂度向空间复杂度的转移- 对数据的操作进行细分,全面掌握数据结构的基础知识
降低复杂度的案例——拼凑100元
假设有任意多张面额为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 ; k < (100/2) ; k++) {
if(i * 7 + j * 3 + k * 2 == 100) {
count++;
}
}
}
}
System.out.println(count);
}
此时代码的时间复杂度为O(n3)
public void s2_2() {
int count = 0;
for(int i = 0 ; i < (100/7) ; i++) {
for(int j = 0 ; j < (100/3) ; j++) {
if((100 - 7 * i - 3 * j) % 2 ==0) {
count++;
}
}
}
System.out.println(count);
}
此时代码的时间复杂度为O(n2)
降低复杂度的案例——查找出现次数最多的数值
输入数组a=[1,2,3,4,5,5,6]中,查找出现次数最多的数值
public void s2_3() {
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 ; i < a.length ; i++) { // 遍历数组
time_tmp = 0;
for(int j = 0 ; j < a.length ; j++) { // 计算每个元素从头到尾出现的次数
if(a[i] == a [j]) {
time_tmp++;
}
if(time_tmp > time_max) {
time_max = time_tmp;
val_max = a[i];
}
}
}
System.out.println(val_max);
}
此时代码的时间复杂度为O(n2),空间复杂度为O(1)
public void s2_4() {
int[] a = {1,2,3,4,5,5,6};
Map<Integer,Integer> d = new HashMap<>();
for(int i = 0 ; i < a.length ; i++) {
if(d.containsKey(a[i])) {
d.put(a[i], d.get(a[i]) + 1);
} else {
d.put(a[i], 1);
}
}
int val_max = -1;
int time_max = 0;
for(Integer key:d.keySet()) {
if(d.get(key) > time_max) {
time_max = d.get(key);
val_max = key;
}
}
System.out.println(vol_max);
}
此时代码的时间复杂度为O(n),空间复杂度增加为O(n)