跟着左神学算法-算法和数据结构
时间复杂度:算法流程中,数据量为n的样本中,执行完整个流程,常数操作的数量关系。
【0-n】数组从小到大排序,下标为0 - n-1,其中最小数位置。选择排序:遍历数组,找到最小数,和数组的第一个数交换位置,遍历除首位的其他数,找到最小数,和下标为1的数交换位置,从下标2开始遍历,找到最小数,和下标2位置的数交换位置,直至结束。
涉及到的操作:没个数都要取出来看一次,每次找最小数都要进行比较:第一次找最小数:n次看+ n-1次比较,在进行交换。第二次:n-1次看 + n-2次比较,交换......
也就是个等差数列。等差数列最终会化成:a*N^2 + b*n + c. + n。
复杂度只要最高阶数,前面的常数也去掉,也就是:时间复杂度: O(n^2).
用最差的数据状况来计算时间复杂度。
空间复杂度:计算整个算法流程所开辟的新的空间的数量,默认已知内容不算在内。
如果说,需要拷贝一个数组,和当前的数组一致,则空间复杂度是O(1),最终结果和初始内容一致,不消耗空间复杂度,仅仅是拷贝过程中的中间变量消耗了空间复杂度。
常见的时间复杂度(我们陆续都会见到的):
排名从好到差: O(1) O(logN) O(N) O(N*logN) O(N^2) O(N^3) … O(N^K) O(2^N) O(3^N) … O(K^N) O(N!)
对数器:用两种不同的思路实现同一个问题的代码,用随机数进行测试,比较两种方式结果是否相同。
异或运算
^:相同为0,不同为1;区别于同或运算:相同为1,不同为0;
异或运算的另外一种计算方式:不进位相加;
异或运算的性质 :
0^N == N N^N == 0
异或运算满足交换律和结合率 上面的两个性质用无进位相加来理解就非常的容易。
同样的数,不管是怎样的异或顺序,结果都一致。
题目一 :如何不用额外变量交换两个数
a=a^b;//a=甲^乙. b=乙
b=a^b;//b=甲^乙^乙=甲 因为:乙^乙=0;甲^0=甲
a=a^b;//a=甲^乙^甲=乙
注意:如果在数组中,两个数使用异或,只能是不同两个位置的数才可以,否则,相同位置的数异或,最后结果一定是0,无法交换;
题目二: 一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数?
只需要eor一个变量,默认为0,从头到尾异或一次,最后变量的结果就是奇数的值。
题目三 :怎么把一个int类型的数,提取出最右侧的1来
a&(a取反加一)
eg:a=10011010000 ~a=01100101111 ~a+1=01100110000 a&(~a+1) = 000000010000
或者可以写成a&(-a). 因为:~a+1 = -a
题目四 :一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这两种数
第一步:需要eor一个变量,默认为0,从头到尾异或一次,结果 eor=a^b, 其中a,b就是两个奇数的异或
a不等于b,则eor 不等于0,所以,此时取出eor中最后一位为1的数(题目3),假设就是10000(倒数第五位是1),此时,ab中一定有一个最后一位是0,另一个数1,只有不同的时候,eor结果才会是1,因此
第二步:将arr数组分成两部分,一部分为倒数第五位是1的,另一部分为倒数第五位是0的,然后遍历arr中倒数第五位是1的数据,新增一个变量eor‘,依次异或,结果eor’=a,此时用eor‘ ^ eor = b;