[charm of data structure] 001 Cognitive complexity & dichotomy & XOR operation

Posted by Leadwing on Tue, 01 Mar 2022 13:25:55 +0100

Constant time operation

If the execution time of an operation is not transferred by the specific sample size, each execution time is a fixed time. Such operations are called constant time operations.

  • Common arithmetic operations (+, -, *, /,%, etc.)
  • Common bit operations (> >, > > >, < <, |, &, ^, etc.)
  • Assignment, comparison, self increasing and self decreasing operations, etc
  • Array addressing operation

How to determine the expression relationship between the total number of operations and the number of samples in the algorithm process?

1. Imagine the data condition processed by the algorithm process, and treat it according to the worst case.

2. Completely split the whole process into basic actions to ensure that each action is a constant time operation.

3. If the amount of data is N, look at the relationship between the number of basic actions and N.

How to determine the time complexity of the algorithm process?

When the expression is established, just leave the highest order term. The lower order terms are removed, and the coefficients of the higher order terms are also removed.

Record as: O (ignore the higher-order term of the coefficient)

Three examples

Select sort

Bubble sorting

Insert sort

The core index of evaluating the advantages and disadvantages of the algorithm

Significance of time complexity

Extra space complexity

Constant term of algorithm flow

Cognitive dichotomy

1) In an ordered array, find whether a number exists

2) In an ordered array, find the leftmost position of > = a number

3) Similarly (2)

4) Find local minimum

Recognize XOR operation

For example:

​ 6 ^ 7

Binary of 6: 110

Binary of 7: 111

​ 110

^ 111 = 001

Properties of XOR operation

1) No extra variables are used to exchange ab

public class ExchangeAB {

    public static void main(String[] args) {
        int a = 1;
        int b= 2;

        a = a ^ b;
        //A is a^b,b is b
        b = a ^ b;
        //b is now a, and a is a^b
        a = a ^ b;
        //A is b, b is a

        System.out.println(a+","+b);
    }
}

2) How to find and print a number in an array that has an odd number of times and other numbers that have an even number of times

public class FindAOdd {
    //Look for the odd number
    public static void findThisNum(int[] arr) {
        int eor = 0;

        for (int i = 0; i < arr.length; i++) {
            eor = eor ^ arr[i];
        }

        System.out.println(eor);
    }

    public static void main(String[] args) {
        /*
            4 One
                3 Two
            4 Three
            2 Four
         */
        int[] arr = {1, 4, 2, 3, 1, 2, 2, 1, 3, 3, 1, 3, 4};
        findThisNum(arr);//2
    }
}

3) How to extract the rightmost 1 from a number of int type

For example:

​ n = 0...011010001000...0

After some transformation

​ n = 0...000000001000...0

Idea: n & (~ n) + 1)

What's the use??? See 4)

4) There are two kinds of numbers in an array that appear odd times and other numbers appear even times. How to find these two kinds of numbers

Idea:

  1. Use a variable eor to XOR all the numbers in the array, and the last eor must be a^b
  2. By known condition a= b. It means that eor must have 1 on a certain bit. At this time, all numbers in the array are divided into two categories (assuming that the x-th bit is 0)
    • The number where the x-th bit is 0 but the total number is even, a (assuming that the x-th bit of a is 0)
    • The x-th bit is 1, but the total number is even, b
  3. Use another variable eor 'to XOR a certain class (assuming the group with bit x as 0). Those even numbers will not interfere. The last eor' must be a, and so will the other group.
public class FindDoubleOdd {

    public static void findDoubleOdd(int[] arr) {
        int eor = 0;
        for (int i = 0; i < arr.length; i++) {
            eor = eor ^ arr[i];
            //eor ^ B at this time
        }
        int rightOne = eor & (~eor + 1);//Extract the number whose rightmost digit is 1
        int seor = 0;
        for (int i = 0; i < arr.length; i++) {
            //(arr[i] & rightOne) !=  0 indicates that the x-bit of I is 1 like rightone
            if ((arr[i] & rightOne) != 0) {
                seor = seor ^ arr[i];
            }
        }
        System.out.println(seor + " " + (eor ^ seor));
    }

    public static void main(String[] args) {
        /*
            3 One
            2 Two
            2 Three
            3 Four
         */
        int[] arr = {1, 1, 1, 2, 2, 3, 3, 4, 4, 4};
        findDoubleOdd(arr);//1,4
    }
}

5) How many bits of a binary number are 1

  1. First find the rightmost 1 of this binary number
  2. Erase this 1
  3. Go round and round until the number is 0
  4. The statistics are erased several times, that is, how many digits are 1
public class FindBit1Counts {

    public static int findBit1Counts(int i){
        int count = 0;

        while (i !=0){
            int rightOne = i&((~i)+1);
            count++;
            i ^= rightOne;
        }
        return count;
    }

    public static void main(String[] args) {
        int i = 6;//0110 2 1
        System.out.println(findBit1Counts(i));
    }
}

Topics: Java data structure Binary Search