认识时间复杂度和异或运算
Posted dxj1016
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了认识时间复杂度和异或运算相关的知识,希望对你有一定的参考价值。
认识时间复杂度和异或运算
1、时间复杂度:
取最高阶的,当一样的时候就不看时间复杂度了,直接代码运行测试看哪个更快就是时间复杂度更好
时间复杂度一律按照最差时间复杂度进行计算,就跟冒泡排序和选择排序,他们的时间复杂度都是O(n^2) ;但是插入排序如果在数组原本有序的情况下进行插入排序,那么他的时间复杂度是O(n),但是最坏的情况下,就是元素刚好是倒序,那么你要排序,就要都交换一遍;所以最坏的时间复杂度是O(n^2);
2、空间复杂度:
如果是有限的数,那么不需要开额外的空间就是o(1);如果是数组需要开一个跟之前一样的就是O(n)
异或运算:相同为0,不同为1(无进位式相加)
3、异或运算满足的条件:
- 其它^a=a a^a=0;
- 满足交换律和结合律
可以用于交换两个数
两个数的值一样的话可以使用异或运算 ,但是如果两个数在不同的内存就出现问题了。比如数组中的i位置和j位置可以交换值的前提是i位置的值不等于j位置的值。否则他们会被覆盖为0;因为会以为是自己跟自己异或,就是a^a=0;这个异或运算是地址之间的运算,如果两个都是基本数据类型,那么比较的就是值,如果不是基本数据类型的话比较的就是地址,地址一样就是自己跟自己异或。
4、异或运算例题
1、在数组中,只有一种数出现了奇数次,其它元素都出现了偶次数,那么求这种数出现了几次
答:定义一个中间量a=0;跟数组中每个元素进行异或运算,结果作为下一个元素运行的值和下一个元素进行异或运算。
2、在数组中,有两种数出现了奇数次,其它元素都出现了偶次数,求出现奇数次的元素。
答:
- 定义一个中间量eor,假设奇数次的元素是a和b,eor与数组元素进行异或运算,最后结果为a^b。 而a^b不等于0;
- 现在如果是二进制形式表示数组元素的值,只要找到一个位置不同那么他们就是不同的数据。奇数次中的如果第八位为1分为一组,为0分为一组,偶次数也一样。那么定义一个eor2;他继续去异或数组中的元素,但是不是全部元素都异或,只要异或第八位是0或者1的就可以了,最后eor2的结果是a or b
- 所以eor2的结果可以得出来一个是出现奇数次的元素,另一个是出现奇数次的元素只要用eor^eor2就可以了。
package 左神算法.异或运算;
public class YiHuoYunSuan
public static void main(String[] args)
int[] arr = 2, 1, 3, 1, 3, 1, 3, 1, 3;
printOddTimeNum1(arr);
int[] arr1 = 2, 1, 3, 1, 3, 1, 3, 1;
printOddTimesNum2(arr1);
//只有一个数出现奇数次
public static void printOddTimeNum1(int[] arr)
int eor = 0;
int count = 0;
for (int i = 0; i < arr.length; i++)
eor ^= arr[i];
for (int i = 0; i < arr.length; i++)
if (arr[i] == eor)
count++;
System.out.println(eor);
System.out.println(count);
//有两个数出现奇数次
public static void printOddTimesNum2(int[] arr)
int eor = 0;
for (int i = 0; i < arr.length; i++)
eor ^= arr[i];
// eor=a^b
// eor!=0
// eor必然有一个位置上是1
int rightOne = eor & (~eor + 1);//提取出最右的1
int onlyOne = 0;//eor1
for (int cur : arr)
if ((cur & rightOne)==1)
onlyOne ^= cur;
System.out.println(onlyOne + " " + (eor ^ onlyOne));
以上是关于认识时间复杂度和异或运算的主要内容,如果未能解决你的问题,请参考以下文章