刷题地址(牛客网):https://www.nowcoder.com/ta/coding-interviews?page=1
**
一。课前必备
**
首先需要了解两个必不可少的概念:时间复杂度和空间复杂度
时间复杂度和空间复杂度是用来评价算法效率高低的2个标准,
*时间复杂度:*就是说执行算法需要消耗的时间长短,越快越好。
*空间复杂度:*就是说执行当前算法需要消耗的存储空间大小,也是越少越好。
时间复杂度
常数阶O(1)
int a = 1;
int b = 2;
int c = 3;
我们假定每执行一行代码所需要消耗的时间为1个时间单位,那么以上3行代码就消耗了3个时间单位。那是不是这段代码的时间复杂度表示为O(n)呢 ?
其实不是的,因为大O符号表示法并不是用于来真实代表算法的执行时间的,它是用来表示代码执行时间的增长变化趋势的。
上面的算法并没有随着某个变量的增长而增长,那么无论这类代码有多长,即使有几万几十万行,都可以用O(1)来表示它的时间复杂度。
线性阶O(n)
for(i = 1; i <= n; i++) {
j = i;
j++;
}
大O符号表示法并不是用于来真实代表算法的执行时间的,它是用来表示代码执行时间的增长变化趋势的”。
所以它的时间复杂度其实是O(n);
对数阶O(logN)
int i = 1;
while(i < n) {
i = i * 2;
}
可以看到每次循环的时候 i 都会乘2,那么总共循环的次数就是log2n,因此这个代码的时间复杂度为O(logn)。
线性对数阶O(nlogN)
for(m = 1; m < n; m++) {
i = 1;
while(i < n) {
i = i * 2;
}
}
线性对数阶O(nlogN) 其实非常容易理解,将时间复杂度为O(logn)的代码循环N遍的话,那么它的时间复杂度就是 n * O(logN),也就是了O(nlogN)。
平方阶O(n²)
for(x = 1; i <= n; x++){
for(i = 1; i <= n; i++) {
j = i;
j++;
}
}
空间复杂度
空间复杂度 O(1)
如果算法执行所需要的临时空间不随着某个变量n的大小而变化,即此算法空间复杂度为一个常量,可表示为 O(1)。
int i = 1;
int j = 2;
++i;
j++;
int m = i + j;
代码中的 i、j、m 所分配的空间都不随着处理数据量变化,因此它的空间复杂度 S(n) = O(1)。
空间复杂度 O(n)
int[] m = new int[n]
for(i = 1; i <= n; ++i) {
j = i;
j++;
}
这段代码中,第一行new了一个数组出来,这个数据占用的大小为n,后面虽然有循环,但没有再分配新的空间,因此,这段代码的空间复杂度主要看第一行即可,即 S(n) = O(n)。