数据结构学习—时间空间复杂度和异或使用
1.时间空间复杂度
一次遍历为n,两层for循环为n^2;
对比时时间复杂度也为n,交换时间复杂度为1(最后为常数c),
时间复杂度只需看幂次,保留幂次最高的就好
比如aN^2+bN+c的时间复杂度为O(N平方)
O()时间复杂度求的是最差情况的复杂度
2.空间复杂度
空间复杂度指的是程序在运行过程中开辟空间的多少,但是在for循环里面开辟的空间在循环结束之后自动释放,不算进空间复杂度当中。
3.异或符号使用
大家先看这一段代码:
a[i]=a[i]^a[j];
a[j]=a[i]^a[j];
a[i]=a[i]^a[j];
是不是感觉比较陌生,其实就是将两个数交换值,跟普通的用temp交换可以省掉一个空间,并且异或运算运行效率比赋值运算更高。
这个到底怎么来的呢,其实就是运用一个交换律以及结合律,异或两个值相同为0,不同为1. 所以在第二行运算时将第一行带入,就会发现a[j]得到的是a[i],最后a[i]得到的就是a[j]了。
来看看具体实例:
求一个数组出现奇数次的数(数组只有一个数出现过奇数次,其他数都为偶数次)
该怎么做呢?其实只需要将数组的每个数一起进行异或运算就能得到出现奇数次的数了
那么如果是求两个出现奇数次的数呢
只需要在第一步的基础上将他进行取反再加一的操作
例如第一步得到的结果存到了值num里面,只需要以下操作:
int numIndex=num&(~num+1);
这样就获得了两个出现奇次数不同位的值,
之后再遍历数组,并且将其分类
if(numIndex~a[i]==1)
num~=a[i]
这就得到了其中一个奇数,最后再将得到的数与numIndex异或,得到另外 一个数的值
整体代码如下
#include<iostream>
using namespace std;
int main(void)
{
int arr[12] = { 1,1,1,1,2,2,2,3,3,3,44,44 };
int num = 0;
for (int curNum : arr)
{
num ^= curNum;
}
int numInd = num & (~num + 1);
for (int curNum : arr)
{
if ((curNum & numInd) == 1)
num ^= curNum;
}
cout << num << endl << (num ^ numInd)<<endl;