Mathematics of "Algorithm Series"

Introduction

  In the mathematics type questions, there are simple nine-year compulsory education mathematics knowledge points, such as finding the area of ​​a rectangle, and finding the slope. There are also more advanced mathematical knowledge points, such as Bash Game, Gray coding and other questions, such questions involving advanced mathematical knowledge points, my personal suggestion is to understand and do more, but don't get entangled . If you know this kind of knowledge point for this kind of question, the code is very simple, but you can't do it if you don't know how. In fact, the test is no longer a question of code algorithm, but more of mathematics. If you are an interviewer, you may not come up with this type of question that memorizes the answer, and there is no screening significance. Of course, if you have enough energy to learn, you can learn more and understand more, and be armed to the teeth.

theoretical basis

  Mathematics is a discipline that uses symbolic language to study concepts such as quantity, structure, change, and space. From a certain perspective, it belongs to a type of formal science . Mathematics arises from counting, calculation, measurement and observation of the shape and motion of objects through the use of abstraction and logical reasoning. Mathematicians extend these concepts in order to formulate new conjectures and to establish rigorously derived theorems from selected axioms and definitions.
  The knowledge and application of fundamental mathematics is an integral part of individual and group life. The perfection of the basic concepts of mathematics can be seen as early as in ancient mathematics texts in ancient Egypt, Mesopotamia and ancient India, and there is a more rigorous treatment in ancient Greece. Since then, the development of mathematics has continued in small increments until the Renaissance in the 16th century, where the interaction of new scientific discoveries and mathematical innovations led to an accelerated development of mathematics until today. Mathematics has become a part of the education category in many countries and regions.
  Today, mathematics is used in a variety of fields, including science , engineering , medicine , economics , and finance . The application of mathematics to these fields is often called applied mathematics, and sometimes it stimulates new mathematical discoveries and leads to the development of entirely new disciplines. For example, certain theories established in the substantive development of physics inspire mathematicians to solve certain problems. thinking from different angles. Mathematicians also study pure mathematics, that is, the substance of mathematics itself, without aiming at any practical application. While much research begins with pure mathematics, many applications are found along the way.
  The end of the computer is mathematics, the end of mathematics is philosophy, and the end of philosophy is theology .

Problem solving experience

  • Mathematics and computers are closely related, and the use of mathematical formulas is of great help to improve the time complexity.
  • In the mathematics category, memorizing answers to questions involving advanced mathematics knowledge points does not need to be too entangled, just understand it, and it will not become the focus of the interview.
  • Learn to express mathematical formulas in computer language.
  • If you have enough energy to learn, you can memorize the questions involving advanced mathematics knowledge.

algorithm topic

7. Integer inversion

insert image description here
Problem analysis: directly convert to long with a larger range, and then force the output after inversion.
code show as below:

/**
 * 数学
 */
class Solution {
    public int reverse(int x) {
        long ret = 0;
        while (x != 0) {
            int pop = x % 10;
            x /= 10;
            ret = ret * 10 + pop;
        }
        if (ret > Integer.MAX_VALUE || ret < Integer.MIN_VALUE) return 0;
        return (int) ret;
    }
}

9. Palindrome number

insert image description here
Topic analysis: After the integer is negated, then compare whether the two values ​​are equal.
code show as below:

/**
 * 数学
 */
class Solution {
    public boolean isPalindrome(int x) {
        // 如果为负数,刚一定不是回文,直接返回false
        if (x < 0) {
            return false;
        }
        int reverseVal = 0;
        int val = x;
        // 对值进行反转
        while (val != 0) {
            int pop = val % 10;
            val /= 10;
            reverseVal = reverseVal * 10 + pop;
        }
        if (reverseVal == x) {
            return true;
        } else {
            return false;
        }
    }
}

50. Pow(x, n)

insert image description here
Topic analysis: Half calculation x^n = (x 2) (n/2) greatly reduces the amount of calculation.
code show as below:

/**
 * 数学
 */
class Solution {
    public double myPow(double x, int n) {
        double res = 1.0D;
        // i每次操作都除2,不用一直相乘
        // i = 1 时,i /= 2 就等于0了
        for (int i = n; i != 0; i /= 2) {
            if (i % 2 != 0) {
                res *= x;
            }
            x *= x;
        }
        // 根据n的正负性,返回正数,还是倒数
        return n < 0 ? 1 / res : res;
    }
}

60. Permutation sequence

insert image description here
Topic Analysis: Backtracking and recursion will time out, which is mainly optimized by mathematical methods. The numbers are continuous natural numbers starting from 1, and the sorting results can be pushed. The expression is: index = k / (n-1)! At this time, index is the index of the remaining candidate numbers.
code show as below:

/**
 * 数学
 */
class Solution {

    public String getPermutation(int n, int k) {

        // 用StringBuilder,比直接用String快1ms,多击败50%选手
        StringBuilder res = new StringBuilder();

        // n为0,直接返回
        if (n == 0) {
            return res.toString();
        }

        // 声明候选数字组
        LinkedList<Integer> nums = new LinkedList();
        for (int i = 1; i <= n; i++) {
            nums.add(i);
        }

        k = k - 1;
        // 查找候选数字
        while (n != 0) {
            // 计算需要第几个侯选值
            int index = k / helper(n - 1);
            res.append(nums.remove(index));
            // 计算k剩余值
            k %= helper(n - 1);
            n--;
        }
        return res.toString();
    }

    // 实现阶乘
    private int helper(int n) {
        int sum = 1;
        for (int i = n; i > 0; i--) {
            sum *= i;
        }
        return sum;
    }
}

66. Plus one

insert image description here
Topic Analysis: Recursively add one in turn.
code show as below:

/**
 * 数学
 */
class Solution {
    public int[] plusOne(int[] digits) {
        int[] res = helper(digits, digits.length - 1);
        return res;
    }

    // 递归加一
    public int[] helper(int[] digits, int index) {
        // 如果进位到首位,直接新建数组返回
        if (index == -1) {
            int[] temp = new int[digits.length + 1];
            temp[0] = 1;
            return temp;
        }
        // 不等于9就加1,等于9就进一位
        if (digits[index] != 9) {
            digits[index] = digits[index] + 1;
            return digits;
        } else {
            digits[index] = 0;
            digits = helper(digits, index - 1);
            return digits;
        }
    }
}

69. Square root of x

insert image description here
Topic Analysis: Dressed in the cloak of mathematics, using the dichotomy.
code show as below:

/**
 * 数学
 */
class Solution {
    public int mySqrt(int x) {
        // 特殊值处理
        if (x == 0 || x == 1) {
            return x;
        }
        int left = 0;
        int right = x;
        int mid = 0;

        // 二分法
        while (left <= right) {
            mid = left + (right - left) / 2;
            if (mid > x / mid) {
                right = mid - 1;
            } else if (mid < x / mid) {
                left = mid + 1;
            } else {
                return mid;
            }
        }
        // 否则返回r
        return right;
    }
}

149. Most points on a straight line

insert image description here
Problem analysis: fix a point, find other points to form a straight line with this point, and count their slopes, the slope with the most times is our answer.
code show as below:

/**
 * 数学 + 哈希表
 */
class Solution {
    public int maxPoints(int[][] points) {
        int n = points.length;
        if (n <= 2) {
            return n;
        }
        int ret = 0;
        for (int i = 0; i < n; i++) {
            if (ret >= n - i || ret > n / 2) {
                break;
            }
            Map<Integer, Integer> map = new HashMap<Integer, Integer>();
            for (int j = i + 1; j < n; j++) {
                int x = points[i][0] - points[j][0];
                int y = points[i][1] - points[j][1];
                if (x == 0) {
                    y = 1;
                } else if (y == 0) {
                    x = 1;
                } else {
                    if (y < 0) {
                        x = -x;
                        y = -y;
                    }
                    int gcdXY = gcd(Math.abs(x), Math.abs(y));
                    x /= gcdXY;
                    y /= gcdXY;
                }
                int key = y + x * 20001;
                map.put(key, map.getOrDefault(key, 0) + 1);
            }
            int maxn = 0;
            for (Map.Entry<Integer, Integer> entry: map.entrySet()) {
                int num = entry.getValue();
                maxn = Math.max(maxn, num + 1);
            }
            ret = Math.max(ret, maxn);
        }
        return ret;
    }

    public int gcd(int a, int b) {
        return b != 0 ? gcd(b, a % b) : a;
    }
}

168. Excel table column names

insert image description here
Topic analysis: The integer is subtracted by 1, and then processed according to the hexadecimal system, because the hexadecimal system starts from 0.
code show as below:

/**
 * 数学
 */
class Solution {
    public String convertToTitle(int columnNumber) {
        StringBuffer sb = new StringBuffer();
        while (columnNumber != 0) {
            columnNumber--;
            sb.append((char)(columnNumber % 26 + 'A'));
            columnNumber /= 26;
        }
        return sb.reverse().toString();
    }
}

171. Excel column number

insert image description here
Topic Analysis: Convert hexadecimal to decimal.
code show as below:

/**
 * 数学
 */
class Solution {
    public int titleToNumber(String columnTitle) {
        int number = 0;
        int multiple = 1;
        for (int i = columnTitle.length() - 1; i >= 0; i--) {
            int k = columnTitle.charAt(i) - 'A' + 1;
            number += k * multiple;
            multiple *= 26;
        }
        return number;
    }
}

172. Zero after factorial

insert image description here
Topic Analysis: Three conclusions can be drawn: 1. You only need to find the number of factors 2 and 5 to determine the number of 0s. Two, the number of 2 is more than 5, so just find the number of factor 5. 3. There is a number divisible by 5 every interval of 5 numbers, and then among these numbers divisible by 5, there is another number divisible by 25 every interval of 5 numbers, so it needs to be divided again until the result is 0 , which means that there is no number that can continue to be divisible by 5.
code show as below:

/**
 * 数学
 */
class Solution {
    public int trailingZeroes(int n) {
        int count = 0;
        while(n >= 5) {
            count += n / 5;
            n /= 5;
        }
        return count;
    }
}

204. Counting Prime Numbers

insert image description here
Topic analysis: Screening method: If x is a prime number, then the multiples of x greater than x 2x, 3x ... must not be prime numbers, so mark them.
code show as below:

/**
 * 数学
 */
class Solution {
    public int countPrimes(int n) {
        int[] isPrime = new int[n];
        // 初始化
        Arrays.fill(isPrime, 1);
        int res = 0;
        for (int i = 2; i < n; ++i) {
            if (isPrime[i] == 1) {
                res += 1;
                if ((long) i * i < n) {
                    for (int j = i * i; j < n; j += i) {
                        // 合数标记为 0 
                        isPrime[j] = 0;
                    }
                }
            }
        }
        return res;
    }
}

223. Rectangular area

insert image description here
Topic Analysis: Geometry: Total Area = Single Area 1 + Single Area 2 - Overlapping Area.
code show as below:

/**
 * 数学
 */
class Solution {
    public int computeArea(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) {
        int area1 = (ax2 - ax1) * (ay2 - ay1), area2 = (bx2 - bx1) * (by2 - by1);
        int overlapWidth = Math.min(ax2, bx2) - Math.max(ax1, bx1), overlapHeight = Math.min(ay2, by2) - Math.max(ay1, by1);
        int overlapArea = Math.max(overlapWidth, 0) * Math.max(overlapHeight, 0);
        return area1 + area2 - overlapArea;
    }
}

233. Number of 1s

insert image description here
Topic Analysis: Enumerate the number of 11 in each digit.
code show as below:

/**
 * 数学
 */
class Solution {
    public int countDigitOne(int n) {
        // mulk 表示 10^k
        // 在下面的代码中,可以发现 k 并没有被直接使用到(都是使用 10^k)
        // 但为了让代码看起来更加直观,这里保留了 k
        long mulk = 1;
        int ans = 0;
        for (int k = 0; n >= mulk; ++k) {
            ans += (n / (mulk * 10)) * mulk + Math.min(Math.max(n % (mulk * 10) - mulk + 1, 0), mulk);
            mulk *= 10;
        }
        return ans;
    }
}

241. Design precedence for arithmetic expressions

insert image description here
Topic analysis: First, do a preprocessing on the expression, put all the operands (including numbers and operators) into the ops array, and use −1, −2, −3 to represent the operators +, −, * respectively. Because for an operator op in an expression, we represent the possible calculation results of its left part with the left set, and the possible calculation results of its right part with the right set. Then all the possible results of the case where the operator is the last operation of the expression are the number of combinations of elements in the corresponding set left and set right corresponding to the operation of the operator. Then we enumerate all the operators in the expression as the left and right separators to obtain the corresponding set, then the final possible result of the expression is the union of these sets.
code show as below:

/**
  * 记忆化搜索
  */
class Solution {
    static final int ADDITION = -1;
    static final int SUBTRACTION = -2;
    static final int MULTIPLICATION = -3;

    public List<Integer> diffWaysToCompute(String expression) {
        List<Integer> ops = new ArrayList<Integer>();
        for (int i = 0; i < expression.length();) {
            if (!Character.isDigit(expression.charAt(i))) {
                if (expression.charAt(i) == '+') {
                    ops.add(ADDITION);
                } else if (expression.charAt(i) == '-') {
                    ops.add(SUBTRACTION);
                } else {
                    ops.add(MULTIPLICATION);
                }
                i++;
            } else {
                int t = 0;
                while (i < expression.length() && Character.isDigit(expression.charAt(i))) {
                    t = t * 10 + expression.charAt(i) - '0';
                    i++;
                }
                ops.add(t);
            }
        }
        List<Integer>[][] dp = new List[ops.size()][ops.size()];
        for (int i = 0; i < ops.size(); i++) {
            for (int j = 0; j < ops.size(); j++) {
                dp[i][j] = new ArrayList<Integer>();
            }
        }
        return dfs(dp, 0, ops.size() - 1, ops);
    }

    public List<Integer> dfs(List<Integer>[][] dp, int l, int r, List<Integer> ops) {
        if (dp[l][r].isEmpty()) {
            if (l == r) {
                dp[l][r].add(ops.get(l));
            } else {
                for (int i = l; i < r; i += 2) {
                    List<Integer> left = dfs(dp, l, i, ops);
                    List<Integer> right = dfs(dp, i + 2, r, ops);
                    for (int lv : left) {
                        for (int rv : right) {
                            if (ops.get(i + 1) == ADDITION) {
                                dp[l][r].add(lv + rv);
                            } else if (ops.get(i + 1) == SUBTRACTION) {
                                dp[l][r].add(lv - rv);
                            } else {
                                dp[l][r].add(lv * rv);
                            }
                        }
                    }
                }
            }
        }
        return dp[l][r];
    }
}

258. Adding the Bits

insert image description here
Topic analysis: Find a regular question. If a three-digit number 'abc' has a value of s1 = 100 * a + 10 * b + 1 * c, after adding the digits once, it becomes s2 = a + b + c, the reduced difference is (s1 -s2) = 99 * a + 9 * b, after each cycle, the reduction is a multiple of 9, so when the last one is a single digit, the total reduction is 9*n, It can be seen from this that we directly take the remainder of 9. If the last num value is not zero, it returns num directly, and returns 9 directly if it is zero.
code show as below:

/**
 * 数学
 */
class Solution {
    public int addDigits(int num) {
        // 为零直接返回
        if (num == 0) {
            return 0;
        }
        // 对9取余,相当于减去 9*n
        num %= 9;
        if (num == 0) {
            return 9;
        }
        return num;
    }
}

263. Ugly Numbers

insert image description here
Topic analysis: divide by 2, 3, and 5 in a loop, and when the remainder is 1, it is an ugly number.
code show as below:

/**
 * 数学
 */
class Solution {
    public boolean isUgly(int n) {
        if (n < 1) {
            return false;
        }
        while (n % 2 == 0) {
            n /= 2;
        }
        while (n % 3 == 0) {
            n /= 3;
        }
        while (n % 5 == 0) {
            n /= 5;
        }
        return n == 1;
    }
}

273. Integer conversion to English representation

insert image description here
Topic analysis: Since the maximum value of the non-negative integer num has been determined, there are at most 10 digits. In converting an integer into English representation, divide the numbers into groups of 3 digits, and concatenate the English representations of each group to obtain the English representation of the integer num.
code show as below:

/**
 * 递归
 */
class Solution {
    String[] singles = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"};
    String[] teens = {"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
    String[] tens = {"", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
    String[] thousands = {"", "Thousand", "Million", "Billion"};

    public String numberToWords(int num) {
        if (num == 0) {
            return "Zero";
        }
        StringBuffer sb = new StringBuffer();
        for (int i = 3, unit = 1000000000; i >= 0; i--, unit /= 1000) {
            int curNum = num / unit;
            if (curNum != 0) {
                num -= curNum * unit;
                StringBuffer curr = new StringBuffer();
                recursion(curr, curNum);
                curr.append(thousands[i]).append(" ");
                sb.append(curr);
            }
        }
        return sb.toString().trim();
    }

    public void recursion(StringBuffer curr, int num) {
        if (num == 0) {
            return;
        } else if (num < 10) {
            curr.append(singles[num]).append(" ");
        } else if (num < 20) {
            curr.append(teens[num - 10]).append(" ");
        } else if (num < 100) {
            curr.append(tens[num / 10]).append(" ");
            recursion(curr, num % 10);
        } else {
            curr.append(singles[num / 100]).append(" Hundred ");
            recursion(curr, num % 100);
        }
    }
}

278. The first wrong version

insert image description here
Topic Analysis: Dichotomy search, note that when the value is too large, you cannot use (left + right)/2, you should use left + (right -left)/2 to prevent overflow.
code show as below:

/**
 * 二分法查找
 */
public class Solution extends VersionControl {
    public int firstBadVersion(int n) {
        int left = 1;
        int right = n;
        while(left <= right){
            int mid = left + (right -left)/2;
            if (isBadVersion(mid)){
                right = mid - 1;
            }else{
                left = mid + 1;
            }
        }
        return left;
    }
}

292. Nim Game

insert image description here
Topic analysis: Bash game, when n % (m+1) != 0, the first player will always win. In the case of both playing, the first hand with an integer of 4 will definitely lose. As long as a takes n first and b takes 4-n, it is guaranteed that b will definitely win, and if the first hand is not an integer of 4, the remainder can be taken away to win. Therefore: To start first, you only need to judge whether the number is a multiple of 4 to judge whether you will win.
The code is as follows:

/**
 * 巴什博奕
 */
class Solution {
    public boolean canWinNim(int n) {
        if(n%4 == 0) return false;
        return true;
    }
}

back to the homepage

Some feelings about brushing Leetcode 500+ questions

Next

"Algorithm Series" tree

Guess you like

Origin blog.csdn.net/qq_22136439/article/details/126322883