LeetCode brushes the power of question-3

Posted by MoldRat on Mon, 31 Jan 2022 01:49:38 +0100

Preface description

Algorithm learning, daily problem brushing records.

Topic connection

Power of 3

Topic content

Given an integer, write a function to determine whether it is a power of 3. If yes, return true; Otherwise, false is returned.

The integer n is to the power of 3, which needs to be satisfied: there is an integer x so that n == 3x

Example 1:

Input: n = 27

Output: true

Example 2:

Input: n = 0

Output: false

Example 3:

Input: n = 9

Output: true

Example 4:

Input: n = 45

Output: false

Tips:

-2^31 <= n <= 2^31 - 1

Advanced:

Can you solve this problem without using loops / recursion?

Analysis process

The solutions to the powers of 2 and 4 have been written earlier,

See the article for the power of 2: Power of 2

See the article for the power of 4: Power of 4

The solution of the power of 4 is based on the power of 2. Can the solution of the power of 3 be used?

Let's first look at the solution of the power of the previous 2:

class Solution {
    public boolean isPowerOfTwo(int n) {
        // The power of 2 must be greater than or equal to 1, and then use the & operation to turn the rightmost bit of 1 of n into 0 by similar calculation of Hamming distance, because except for 1, only 1 bit of the power of 2 is 1, so if this 1 becomes 0, the result will become 0, that is, after the & operation is equal to 0, it is the power of 2
        return n >= 1 && (n & (n - 1)) == 0;
    }
}

Let's look at the solution to the power of the previous 4:

class Solution {
    public boolean isPowerOfFour(int n) {
        // The power of 2 must be greater than or equal to 1, and then use the & operation to turn the rightmost bit of 1 of n into 0 by similar calculation of Hamming distance, because except for 1, only 1 bit of the power of 2 is 1, so if this 1 becomes 0, the result will become 0, that is, after the & operation is equal to 0, it is the power of 2
        // The power of 4 must be the power of 2. First judge the power of 2 by judging the power of 2. If the first bit is the 0 bit from the right, then the 1 of the power of 4 is in the even digit. Therefore, just judge whether the even digit of n is 1, construct the 32-bit binary number 1010 1010 1010 1010 1010 1010 1010 1010 1010 1010, and use n and it for & operation. If it is the power of 4, the result will be 0, For ex amp le, if the binary of 4 is 0100, then n performs & operation with it, and the result is 0, so it is the power of 4. If it is 2, then its binary is 0010. Then n performs & operation with it, and the result is 0010, not 0, and 2 is not the power of 4. Therefore, this method can be used to judge the power of 4. Then 1010 1010 1010 1010 1010 1010 1010 1010 1010 can be represented by hexadecimal 0xaaaaaa
        return n >= 1 && (n & (n - 1)) == 0 && (n & 0xaaaaaaaa) == 0;
    }
}

Then the power of 3 can be analogized. Add a bit operation judgment on the basis of the power of 2 to judge whether it is the power of 3? I didn't think of such a method for the time being. If you think of it, please say it.

Method 1

Let's go back to the honest circulation method first.

If a number is a power of 3, it must be a multiple of 3, and divided by 3, it is still a multiple of 3, and then divided by 3 until it finally becomes 1. You can give several examples.

For example, 9, 9 / 3 = 3, 3 / 3 = 1, and finally it is 1. 9 is the power of 3.

For example, 27, 27 / 3 = 9, 9 / 3 = 3, 3 / 3 = 1, and finally it is 1. 27 is the power of 3.

If this number is not a power of 3, it will not be equal to 1 until it is divided by 3. You can give several examples.

For example, 15, 15 / 3 = 5, and 5 / 3 is not 1. Although 15 is a multiple of 3, not all factors after decomposition are 3, and 15 is not a power of 3.

For example, 4, 4 / 3 is not 1, and 4 is not a power of 3.

Therefore, we can get the solution code from the above. By constantly dividing by 3, we can constantly judge the remainder of 3. Finally, if we get 1, it is the power of 3. The code is as follows:

class Solution {
    public boolean isPowerOfThree(int n) {
        if (n < 1) {
           // The power of 3 must be greater than or equal to 1. If it is less than 1, it is directly determined as No
           return false;
        }
    
        // If a number is a power of 3, it must be a multiple of 3, and it is still a multiple of 3 after dividing by 3, and then divided by 3 until it is finally 1. If the last is not 1, it is proved that although the number is a multiple of 3, not all factors are 3, so it is not a power of 3
        while (n % 3 == 0) {
           n /= 3;
        }

        // The last step is to judge whether it is 1. If it is 1, it is proved that n is the power of 3. If it is not 1, it is proved that n is not the power of 3
        return n == 1;
    }
}

After submitting the code, the execution time is 15ms, the time beats 98.31% of users, the memory consumption is 38.2MB, and the space beats 67.49% of users.

Method 2

Method 1 seems a little troublesome. Is there a simpler method? Can you solve this problem without using loops / recursion? Is there a simple answer code like the power of 2 and the power of 4?

There's really a strange technique.

The previous power of 2 has a Sao operation, which directly lists all the powers of 2 in an integer. Of course, this operation is not used to solve the power of 3.

But we can use that idea to calculate the power of the largest 3 in the integer and write a java program to list the powers of 3 one by one, starting from 1. Because the maximum value of an integer is 2 ^ 31 - 1, the maximum power of 2 is 2 ^ 30, so the maximum power of 3 must be less than the power of 30, but how much is it?

It can be judged by writing a java program. Refer to the method of enumerating all the powers of 2 mentioned in the power of 2. The code is as follows:

public class Main {

    public static void main(String[] args) {
        showAllThreePower();
    }

    private static void showAllThreePower() {
        int num = 1;

        for (int i = 0; i <= 30; ++i) {
            System.out.println("3 of" + i + "Power:" + num);
            num *= 3;
        }
    }

}

Print results:

We can see that it becomes negative at the 20th power of 3. Because it has overflowed, the 19th power of 3 is the maximum power of 3 in the integer, so the maximum power of 3 is 116261467.

We can find that if the input value is a power of 3, the remainder will be equal to 0; If the input value is not a power of 3, the remainder is not equal to 0.

Because 3 is a prime number, and the power of 3 can only be decomposed into multiple 3 or 1 multiplication, then for divisor, if you want to divide completely, you can only be the power of 3, otherwise there must be remainder.

Therefore, you can judge whether the number is a power of 3 by summing the input value with 116261467. The code is as follows:

class Solution {
    public boolean isPowerOfThree(int n) {
        // Through calculation, the maximum value of the power of 3 in the integer range is 3 ^ 19. Because the answer of 3 ^ 20 is negative, it proves that overflow has begun, so the power of 19 is the maximum value
        // So the power of 3 in the integer range is: 3 ^ 0, 3 ^ 1, 3 ^ 2 3^19
        // Use the maximum power of 3 to find the remainder of the input n. if the input n is a power of 3, the remainder will be equal to 0; If the input n is not a power of 3, the remainder is not equal to 0; Because 3 is a prime number, the power of 3 can only be decomposed into multiple 3 or 1 multiplication, so for divisor, if you want to divide completely, you can only be the power of 3, otherwise there must be remainder
        return n >= 1 && 1162261467 % n == 0;
    }
}

After submitting the code, the execution time is 15ms, the time beats 98.30% of users, the memory consumption is 38.2MB, and the space beats 69.43% of users.

I feel something is wrong. It's even slower than method 1. Submitting more times is almost the same result.

However, we can know that the time complexity of method 2 is O(1), and method 1 has a while loop. Its time complexity is greater than O(1) and has n, so it must be that method 2 runs faster.

There's something wrong here, confused (• • •)?

Original link

Original link: Power of 3

Topics: Java Algorithm leetcode