时间复杂度是一个函数,它定性描述该算法的运行时间。
假设算法的问题规模为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)(否则会导致访问越界), 这其实就是所谓的循环不变量。因此要清楚对查找区间的定义,在循环中根据查找区间的定义来做边界处理。 class Solution {public: int search(vector class Solution {public: // 无重复元素 int searchInsert(vector 循环判断中,等于target的情况不跳出循环,继续移动搜索指针,最终将会导致 left = right + 1 的情况而跳出循环。 class Solution {public: int searchInsert(vector class Solution {public: int searchInsert(vector 1、遍历 class Solution {public: vector 2、 二分法 class Solution {public: // 寻找第一个大于或等于 num 的位置索引, 找不到则返回数组长度 (相当于 35、搜索插入位置) int search (vector 找到满足 k 2 ≤ x k^2 ≤ x k2≤x 的最大 k k k 值,即寻找最后一个 k 2 k^2 k2小于或等于 x x 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; }}; 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; }};
定义查找区间为 [left, right] 或 [left, right),LeetCode示例: