Fast power + bit operation--->Do not use * ÷ sign to implement multiplication and division operations

Small knowledge point: standard writing method for calculating median value (preventing overflow)

 int mid = left + ((right - left) >> 1);

Use of fast powers:

Find 5^16 (that is, find the nth power of x):
Conventional solution: take the initial value as 1, and
multiply

Fast power solution method: Treat n as binary (that is, treat 16 as 10000, thus reducing the number of operations from 16 to 5). The operation
process:
1. Set the initial value res as 1
2. Determine the rightmost digit of the binary number of n , if 1, res *= x;
judgment code:

 n & 1 


3. Iterate over x:
Benefits: Greatly reduces time

Title: leetcode50
implements pow(x, n), that is, calculates the nth power function of x (i.e., xn)

class Solution {
    
    
    public double myPow(double x, int n) {
    
    
        if(x == 0.0f) return 0.0d;
        long b = n;
        double res = 1.0;
        if(b < 0) {
    
    
            x = 1 / x;
            b = -b;
        }
        while(b > 0) {
    
    
            if((b & 1) == 1) res *= x;
            x *= x;
            b >>= 1;
        }
        return res;
    }
}

Detailed explanation of fast power:
Explanation by leetcode’s boss

Migration:
Complete multiplication and division without using the * ÷ sign.
Example 5 x 16 (Y x Z)
Conventional solution: Use 0 as the initial value, the largest number Z as the summand, and the smallest number Y as the number of additions, that
is, 5 consecutive additions 16. When Y is very large, it is quite time-consuming,
so you can use fast power: treat Y as a binary number.
Process:
1. The initial value of res is 0.
2. Y & 1 is used to determine whether the rightmost bit is 1. If so, res += Z, otherwise no operation will be performed
3. Iterate Z: Z <<= 1 (shifting one bit to the left is equivalent to expanding by 2 times. According to the 8421 code, each operation must be expanded after each operation, corresponding to each digit The values ​​have a one-to-one correspondence)
4. Iterate Y: Y >>= 1 and remove the rightmost bit
5. End when Y is 0, if not 0, repeat the operation of step 234

Question: leetcode29
Given two integers, dividend and divisor. To divide two numbers, do not use multiplication, division and mod operators.

Returns the quotient of dividend divided by divisor.

The result of integer division should have its decimal part truncated, for example: truncate(8.345) = 8 and truncate(-2.7335) = -2

class Solution {
    
    
    public int divide(int dividend, int divisor) {
    
    
        // 考虑被除数为最小值的情况
        if (dividend == Integer.MIN_VALUE) {
    
    
            if (divisor == 1) {
    
    
                return Integer.MIN_VALUE;
            }
            if (divisor == -1) {
    
    
                return Integer.MAX_VALUE;
            }
        }
        // 考虑除数为最小值的情况
        if (divisor == Integer.MIN_VALUE) {
    
    
            return dividend == Integer.MIN_VALUE ? 1 : 0;
        }
        // 考虑被除数为 0 的情况
        if (dividend == 0) {
    
    
            return 0;
        }
        
        // 一般情况,使用二分查找
        // 将所有的正数取相反数,这样就只需要考虑一种情况
        boolean rev = false;
        if (dividend > 0) {
    
    
            dividend = -dividend;
            rev = !rev;
        }
        if (divisor > 0) {
    
    
            divisor = -divisor;
            rev = !rev;
        }
        
        int left = 1, right = Integer.MAX_VALUE, ans = 0;
        while (left <= right) {
    
    
            // 注意溢出,并且不能使用除法
            int mid = left + ((right - left) >> 1);
            boolean check = quickAdd(divisor, mid, dividend);
            if (check) {
    
    
                ans = mid;
                // 注意溢出
                if (mid == Integer.MAX_VALUE) {
    
    
                    break;
                }
                left = mid + 1;
            } else {
    
    
                right = mid - 1;
            }
        }

        return rev ? -ans : ans;
    }

    // 快速乘
    public boolean quickAdd(int y, int z, int x) {
    
    
        // x 和 y 是负数,z 是正数
        // 需要判断 z * y >= x 是否成立
        int result = 0, add = y;
        while (z != 0) {
    
    
            if ((z & 1) != 0) {
    
    
                // 需要保证 result + add >= x
                if (result < x - add) {
    
    
                    return false;
                }
                result += add;
            }
            if (z != 1) {
    
    
                // 需要保证 add + add >= x
                if (add < x - add) {
    
    
                    return false;
                }
                add += add;
            }
            // 不能使用除法
            z >>= 1;
        }
        return true;
    }
}

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/divide-two-integers/solution/liang-shu-xiang-chu-by-leetcode-solution-5hic/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Official dichotomy answer, watch it by yourself, take notes for easy sorting

Guess you like

Origin blog.csdn.net/XJ200012/article/details/122487791