1对数器二分法异或运算

时间复杂度

选择排序、冒泡排序、插入排序

//选择排序
public static void selectionSort(int[] arr){
     
        if(arr == null ||arr.length < 2){
     
            return;
        }
        for(int i = 0;i < arr.length;i++){
     
            int minIndex = i;
            for(int j = i + 1;j < arr.length;j++){
     
                minIndex = arr[j] < arr[minIndex] ? j : minIndex;
            }
            swap(arr,i,minIndex);
        }
    }
//冒泡排序
 public  static  void  bubbleSort(int[] arr){
     
        if(arr == null ||arr.length < 2){
     
            return;
        }
        for(int e = arr.length-1;e > 0;e--){
     
            for(int i = 0;i < e;i++){
     
                if(arr[i] > arr[i + 1]){
     
                    swap(arr,i,i+1);
                }
            }
        }
    }
//插入排序
public  static  void  insertionSort(int[] arr){
     
        if(arr == null ||arr.length < 2){
     
            return;
        }
        for(int i = 1;i < arr.length;i++){
     
            for(int j = i - 1;j >= 0 && arr[j] > arr[j + 1];j--){
     
                swap(arr,j,j+1);
            }
        }
    }

额外空间复杂度:为实现算法,自己需要的额外空间

对数器:测试、调试

public static int[] generateRandomArray(int maxSize,int maxValue){
     
        int[] arr = new int[(int)((maxSize + 1) * Math.random())];//Math.random()随机生成[0,1)
        for(int i = 0;i < arr.length;i++){
     
            arr[i] = (int)((maxValue + 1) * Math.random());
        }
        return arr;
    }

两个数相加,当心溢出(计算两个中点)

(a+b)/2优化写法:a+((a-b)>>1)

a*2+1优化写法:(a<<1) | 1

二分法:

  1. 在一个有序数组中,找某个数是否存在
  2. 在一个有序数组中,找>=某个数最左侧的位置
  3. 在一个有序数组中,找<=某个数最左侧的位置
  4. 局部最小值问题
//在一个有序数组中,找某个数是否存在
public static boolean exit(int[] sortedArr,int num){
     
        if(sortedArr == null || sortedArr.length == 0){
     
            return false;
        }
        int L = 0;
        int R = sortedArr.length - 1;
        int mid = 0;
        while (L < R){
     
            mid = L + ((R - L) >> 1);
            if(sortedArr[mid] == num){
     
                return true;
            }else if(sortedArr[mid] > num){
     
                R = mid - 1;
            }else {
     
                L = mid + 1;
            }
        }
        return sortedArr[L] == num;
    }
//在一个有序数组中,找>=某个数最左侧的位置
//在一个有序数组中,找<=某个数最左侧的位置
public static int nearestIndex(int[] sortedArr,int num){
     
        if(sortedArr == null || sortedArr.length == 0){
     
            return -1;
        }
        int L = 0;
        int R = sortedArr.length - 1;
        int mid = 0;
        int index = -1;
        while (L <= R){
     
            mid = L + ((R - L) >> 1);
            if(sortedArr[mid] >= num){
     
                index = mid;
                R = mid - 1;
            }else {
     
                L = mid + 1;
            }
        }
        return index;
    }
//局部最小值问题
 public static int getLessIndex(int[] arr){
     
        if(arr == null || arr.length == 0){
     
            return -1;
        }
        if(arr.length == 1 || arr[0] < arr[1]){
     
            return 0;
        }
        if(arr[arr.length - 1] < arr[arr.length - 2]){
     
            return arr.length - 1;
        }
        int left = 1;
        int right = arr.length - 2;
        int mid = 0;
        while (left < right){
     
            mid = left + ((right - left) >> 1);
            if(arr[mid] > arr[mid -1]){
     
                right = mid - 1;
            }else if(arr[mid] > arr[mid + 1]){
     
                left = mid + 1;
            }else{
     
                return mid;
            }
        }
        return left;
    }

异或运算(无进位相加)

//一个数组中有一种数出现奇数次,其他都是偶数次
public static void printOddTimesNum1(int[] arr){
     
    int eor = 0;
    for(int i = 0;i < arr.length;i++){
     
        eor ^= arr[i];
    }
    System.out.println(eor);
}
//一个数组中有两种数出现奇数次
public static void printOddTimesNum2(int[] arr){
     
    int eor = 0;
    for(int i = 0;i < arr.length;i++){
     
        eor ^= arr[i];
    }
    int rightOne = eor & (~eor + 1);//获取二进制低位1: N & (~N + 1)
    int eor1 = 0;
    for(int i = 0;i < arr.length;i++){
     
        if(arr[i] & rightOne == 0){
     
            eor1 ^= arr[i];
        }
    }
    System.out.println(eor1 + " " + (eor ^ eor1));
}
//数出二进制中1的个数
public static int bit1Counts(int num){
     
    int count = 0;
    while(num != 0){
     
        int rightOne = num & (~num + 1);
        count++;
        num ^= rightOne;
    }
    return count;
}

你可能感兴趣的:(1对数器二分法异或运算)