认识时间复杂度和异或运算

Posted dxj1016

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了认识时间复杂度和异或运算相关的知识,希望对你有一定的参考价值。

认识时间复杂度和异或运算

1、时间复杂度:

取最高阶的,当一样的时候就不看时间复杂度了,直接代码运行测试看哪个更快就是时间复杂度更好

时间复杂度一律按照最差时间复杂度进行计算,就跟冒泡排序和选择排序,他们的时间复杂度都是O(n^2) ;但是插入排序如果在数组原本有序的情况下进行插入排序,那么他的时间复杂度是O(n),但是最坏的情况下,就是元素刚好是倒序,那么你要排序,就要都交换一遍;所以最坏的时间复杂度是O(n^2);

2、空间复杂度:

如果是有限的数,那么不需要开额外的空间就是o(1);如果是数组需要开一个跟之前一样的就是O(n)

异或运算:相同为0,不同为1(无进位式相加)

3、异或运算满足的条件:

  1. 其它^a=a a^a=0;
  2. 满足交换律和结合律

可以用于交换两个数

两个数的值一样的话可以使用异或运算 ,但是如果两个数在不同的内存就出现问题了。比如数组中的i位置和j位置可以交换值的前提是i位置的值不等于j位置的值。否则他们会被覆盖为0;因为会以为是自己跟自己异或,就是a^a=0;这个异或运算是地址之间的运算,如果两个都是基本数据类型,那么比较的就是值,如果不是基本数据类型的话比较的就是地址,地址一样就是自己跟自己异或。

4、异或运算例题

1、在数组中,只有一种数出现了奇数次,其它元素都出现了偶次数,那么求这种数出现了几次

答:定义一个中间量a=0;跟数组中每个元素进行异或运算,结果作为下一个元素运行的值和下一个元素进行异或运算。

2、在数组中,有两种数出现了奇数次,其它元素都出现了偶次数,求出现奇数次的元素。

答:

  1. 定义一个中间量eor,假设奇数次的元素是a和b,eor与数组元素进行异或运算,最后结果为a^b。 而a^b不等于0;
  2. 现在如果是二进制形式表示数组元素的值,只要找到一个位置不同那么他们就是不同的数据。奇数次中的如果第八位为1分为一组,为0分为一组,偶次数也一样。那么定义一个eor2;他继续去异或数组中的元素,但是不是全部元素都异或,只要异或第八位是0或者1的就可以了,最后eor2的结果是a or b
  3. 所以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));
    

以上是关于认识时间复杂度和异或运算的主要内容,如果未能解决你的问题,请参考以下文章

java的移位和异或运算

C语言重点难点:与,或和异或

算法入门(零,认识复杂度,对数器,异或运算)

清北学堂模拟赛d1t6 或和异或(xor)

『线性空间 整数线性基和异或线性基』

什么是与门、或门、非门和异或门