时间复杂度是一个函数,它定性描述该算法的运行时间。
假设算法的问题规模为n,算法的渐近时间复杂度,简称时间复杂度,记为 O ( f ( n ) ) O(f(n)) O(f(n))。
大O用来表示上界的,当用它作为算法的最坏情况运行时间的上界,就是对任意数据输入的运行时间的上界。
但是业内的一个默认规定,O代表的就是一般情况,而不是严格的上界。
深入探讨一个算法的实现以及性能的时候,就要时刻想着数据用例的不一样,时间复杂度也是不同的。
空间复杂度O(1)常数阶 < O ( log n ) O(log n) O(logn)对数阶 < O ( n ) O(n) O(n)线性阶 < O ( n log n ) O(nlog n) O(nlogn) < O ( n 2 ) O(n^2) O(n2)平方阶 < O ( n 3 ) O(n^3) O(n3)立方阶 < O ( 2 n ) O(2^n) O(2n)指数阶 < O ( n ! ) O(n!) O(n!) < O ( n n ) O(n^n) O(nn)log n忽略底数的描述
空间复杂度预估程序运行时占用内存的大小,而不是可执行文件的大小。
数组数组是存放在连续内存空间上的相同类型数据的集合。
二分查找在升序数组 nums 中寻找目标值 target,对于特定下标 i,比较nums[ i ] 和 target 的大小:
如果
n
u
m
s
[
i
]
=
t
a
r
g
e
t
nums[i] = target
nums[i]=target,则下标 i 即为要寻找的下标;如果
n
u
m
s
[
i
]
>
t
a
r
g
e
t
nums[i] > target
nums[i]>target,则 target只可能在下标i的左侧;如果
n
u
m
s
[
i
]
<
t
a
r
g
e
t
nums[i] < target
nums[i] 基于上述事实,可以在有序数组中使用二分查找寻找目标值,每次查找都会将查找范围缩小一半。 时间复杂度:
O
(
log
n
)
O(log n)
O(logn),其中 n 是数组的长度空间复杂度:
O
(
1
)
O(1)
O(1)
每次循环中 left 和 right 共同约束了本次查找的范围, 要让本次循环与上一次循环查找的范围既不重复(重复了会引起死循环), 也不遗漏, 并且要让 left 和 right 共同约束的查找的范围变得无意义时不再进行查找(即跳出 while)(否则会导致访问越界), 这其实就是所谓的循环不变量。因此要清楚对查找区间的定义,在循环中根据查找区间的定义来做边界处理。 循环判断中,等于target的情况不跳出循环,继续移动搜索指针,最终将会导致 left = right + 1 的情况而跳出循环。 1、遍历 2、 二分法 找到满足
k
2
≤
x
k^2 ≤ x
k2≤x 的最大
k
k
k 值,即寻找最后一个
k
2
k^2
k2小于或等于
x
x
x 的位置索引。
定义查找区间为 [left, right] 或 [left, right),LeetCode示例:class Solution {
public:
int search(vector
35. 搜索插入位置
class Solution {
public:
// 无重复元素
int searchInsert(vector
class Solution {
public:
int searchInsert(vector
class Solution {
public:
int searchInsert(vector
34.在排序数组中查找元素的第一个和最后一个位置
class Solution {
public:
vector
class Solution {
public:
// 寻找第一个大于或等于 num 的位置索引, 找不到则返回数组长度 (相当于 35. 搜索插入位置)
int search (vector
69.x的平方根
class Solution {
public:
// 二分查找
int mySqrt(int x) {
int left = 0;
int right = x;
int ans = 0;
while (left <= right){
int mid = left + (right - left) / 2;
if ((long long)mid * mid > x){
right = mid - 1; // 寻找最后一个小于或等于 num 的位置索引
}
else{ // (long long)mid * mid <= x
left = mid + 1;
}
}
return right;
}
};
367.有效的完全平方数
class Solution {
public:
bool isPerfectSquare(int num) {
int left = 0;
int rigth = num;
while (left <= rigth){
int mid = left + (rigth - left) / 2;
long square = (long) mid * mid;
if (square > num){ // 二分查找条件
rigth = mid - 1;
}
else if (square < num){
left = mid + 1;
}
else{
return true;
}
}
return false;
}
};



