1. 程式人生 > 實用技巧 >LeetCode 數學

LeetCode 數學

基礎部分

204. 計數質數

簡單

統計所有小於非負整數 n 的質數的數量。

示例:

輸入: 10
輸出: 4
解釋: 小於 10 的質數一共有 4 個, 它們是 2, 3, 5, 7 。
class Solution {
    public int countPrimes(int n) {
        if (n < 2) return 0;
        boolean[] dp = new boolean[n];
        int res = 0;
        for (int i = 2; i < n; i++)
            if (!dp[i]) {
                res++;
                for (int j = 2; i*j < n; j++){
                    dp[i*j] = true;
                }
            }
        return res;
    }
}

504. 七進位制數

簡單

給定一個整數,將其轉化為7進位制,並以字串形式輸出。

示例 1:

輸入: 100
輸出: "202"

示例 2:

輸入: -7
輸出: "-10"

注意: 輸入範圍是 [-1e7, 1e7] 。

class Solution {
    public String convertToBase7(int num) {
        if (num == 0) return "0";
        String sign = "";
        if (num < 0){
            num = - num;
            sign += "-";
        }
        StringBuilder ans = new StringBuilder();
        while (num > 0){
            int add = num % 7;
            ans.append(add);
            num /= 7;
        }
        return sign + String.valueOf(ans.reverse());
    }
}

405. 數字轉換為十六進位制數

簡單

給定一個整數,編寫一個演算法將這個數轉換為十六進位制數。對於負整數,我們通常使用 補碼運算 方法。

注意:

  1. 十六進位制中所有字母(a-f)都必須是小寫。
  2. 十六進位制字串中不能包含多餘的前導零。如果要轉化的數為0,那麼以單個字元'0'來表示;對於其他情況,十六進位制字串中的第一個字元將不會是0字元。
  3. 給定的數確保在32位有符號整數範圍內。
  4. 不能使用任何由庫提供的將數字直接轉換或格式化為十六進位制的方法。

示例 1:

輸入:
26

輸出:
"1a"

示例 2:

輸入:
-1

輸出:
"ffffffff"
class Solution {
    public String toHex(int num) {
        char[] digits = new char[16]; //字典
        for (int i = 0; i < 10; i++)
            digits[i] = (char) (i + (int)'0') ;
        for (int i = 10; i < 16; i++)
            digits[i] = (char) (i - 10 + (int)'a');
        int a = 15;
        StringBuilder sb = new StringBuilder();
        while (num != 0){
            int add = num & a;
            num = num >>> 4;
            sb.append(digits[add]);
        }
        return sb.length()==0 ? "0" : sb.reverse().toString();
    }
}

168. Excel表列名稱

簡單

給定一個正整數,返回它在 Excel 表中相對應的列名稱。

例如,

    1 -> A
    2 -> B
    3 -> C
    ...
    26 -> Z
    27 -> AA
    28 -> AB 
    ...

示例 1:

輸入: 1
輸出: "A"

示例 2:

輸入: 28
輸出: "AB"

示例 3:

輸入: 701
輸出: "ZY"
class Solution {
    public String convertToTitle(int n) {
        char[] letters = new char[26];
        for (int i = 0; i < 26; i++)
            letters[i] = (char)(i+(int)'A');
        StringBuilder res = new StringBuilder();
        while (n != 0){
            n--; //※※※,從1開始算的,而不是從0開始,所以要減1
            int add = (n) % 26;
            n = n / 26;
            res.append(letters[add]);
        }
        return res.reverse().toString();
    }
}

172. 階乘後的零

簡單

給定一個整數 n,返回 n! 結果尾數中零的數量。

示例 1:

輸入: 3
輸出: 0
解釋: 3! = 6, 尾數中沒有零。

示例 2:

輸入: 5
輸出: 1
解釋: 5! = 120, 尾數中有 1 個零.
class Solution {
    public int trailingZeroes(int n) {
        int res = 0;
        while (n != 0){
            n /= 5; //每乘一個5加一個量級
            res += n;
        }
        return res;
    }
}

67. 二進位制求和

簡單

給你兩個二進位制字串,返回它們的和(用二進位制表示)。

輸入為 非空 字串且只包含數字 10

示例 1:

輸入: a = "11", b = "1"
輸出: "100"

示例 2:

輸入: a = "1010", b = "1011"
輸出: "10101"

提示:

  • 每個字串僅由字元 '0''1' 組成。
  • 1 <= a.length, b.length <= 10^4
  • 字串如果不是 "0" ,就都不含前導零。
class Solution {
    public String addBinary(String a, String b) {
        StringBuilder res = new StringBuilder();
        int la = a.length();
        int lb = b.length();
        int len = Math.max(la,lb), carry = 0;
        for (int i = 0; i < len; i++){
            carry += la-1-i < 0 ? 0 : (int)a.charAt(la-1-i)-'0';
            carry += lb-1-i < 0 ? 0 : (int)b.charAt(lb-1-i)-'0';
            res.append(carry%2);
            carry /= 2;
        }
        if (carry == 1) res.append(carry);
        return res.reverse().toString();
    }
}
//自帶函式
return Integer.toBinaryString(Integer.parseInt(a, 2) + Integer.parseInt(b, 2));

415. 字串相加

簡單

給定兩個字串形式的非負整數 num1num2 ,計算它們的和。

注意:

  1. num1num2 的長度都小於 5100.
  2. num1num2 都只包含數字 0-9.
  3. num1num2 都不包含任何前導零。
  4. 你不能使用任何內建 BigInteger 庫, 也不能直接將輸入的字串轉換為整數形式。
class Solution {
    public String addStrings(String num1, String num2) {
        int la = num1.length(), lb = num2.length();
        int len = la > lb ? la : lb, carry = 0;
        StringBuilder res = new StringBuilder();
        for (int i = 0; i < len; i++){
            carry += la-1-i < 0 ? 0 : (int)num1.charAt(la-1-i) - '0';
            carry += lb-1-i < 0 ? 0 : (int)num2.charAt(lb-1-i) - '0';
            res.append(carry%10);
            carry /= 10;
        }
        if (carry > 0) res.append(carry);
        return res.reverse().toString();
    }
}

462. 最少移動次數使陣列元素相等 II

中等

給定一個非空整數陣列,找到使所有陣列元素相等所需的最小移動數,其中每次移動可將選定的一個元素加1或減1。 您可以假設陣列的長度最多為10000。

例如:

輸入:
[1,2,3]

輸出:
2

說明:
只有兩個動作是必要的(記得每一步僅可使其中一個元素加1或減1): 

[1,2,3]  =>  [2,2,3]  =>  [2,2,2]
class Solution { //全排序,4ms
    public int minMoves2(int[] nums) {
        Arrays.sort(nums); //可以減治,找中位數,懶得寫了
        int res = 0;
        int mid = nums[nums.length/2];
        for (int num : nums){
            res += Math.abs(mid-num);
        }
        return res;
    }
}
class Solution { //快排,更慢了,73ms
    public int minMoves2(int[] nums) {
        if (nums.length < 2) return 0;
        int res = 0;
        int mid = helper(nums,0,nums.length-1,nums.length/2);
        for (int num : nums)
            res += Math.abs(mid-num);
        return res;
    }

    private int helper(int[] nums, int l, int r, int correct){
        if (l == r) return nums[r];
        int first = nums[l];
        int i = l;
        int j = r + 1;
        while (i < j){
            do{
                i++;
            }while (i < r && nums[i] < first);
            do{
                j--;
            }while (l < j && nums[j] > first);
            if (i >= j) break;
            int tmp = nums[i];
            nums[i] = nums[j];
            nums[j] = tmp;
        }
        int tmp = nums[l];
        nums[l] = nums[j];
        nums[j] = tmp;
        if (j == correct) return nums[j];
        else if (j < correct) return helper(nums, j+1, r, correct);
        else return helper(nums, l, j-1, correct);
    }
}

169. 多數元素

簡單

給定一個大小為 n 的陣列,找到其中的多數元素。多數元素是指在陣列中出現次數大於 ⌊ n/2 ⌋ 的元素。

你可以假設陣列是非空的,並且給定的陣列總是存在多數元素。

示例 1:

輸入: [3,2,3]
輸出: 3

示例 2:

輸入: [2,2,1,1,1,2,2]
輸出: 2
class Solution {
    public int majorityElement(int[] nums) {
        Arrays.sort(nums);
        return nums[nums.length/2];
    }
}
class Solution {
    public int majorityElement(int[] nums) {
        int count = 1, cur = nums[0];
        for (int i = 1; i < nums.length; i++){
            if (cur == nums[i]) count++;
            else if (count > 0) count--;
            else {
                cur = nums[i];
                count = 1;
            }
        }
        return cur;
    }
}

367. 有效的完全平方數

簡單

給定一個正整數 num,編寫一個函式,如果 num 是一個完全平方數,則返回 True,否則返回 False。

說明:不要使用任何內建的庫函式,如 sqrt

示例 1:

輸入:16
輸出:True

示例 2:

輸入:14
輸出:False
class Solution {
    public boolean isPerfectSquare(int num) {
        long a = 0;
        for (int i = 1; i < num+1; i++){
            a = i * i;
            if (a >= num) break;
        }
        return a == num;
    }
}

326. 3的冪

簡單

給定一個整數,寫一個函式來判斷它是否是 3 的冪次方。

示例 1:

輸入: 27
輸出: true

示例 2:

輸入: 0
輸出: false

示例 3:

輸入: 9
輸出: true

示例 4:

輸入: 45
輸出: false

進階:
你能不使用迴圈或者遞迴來完成本題嗎?

class Solution {
    public boolean isPowerOfThree(int n) {
        while (n > 1) {
            if (n%3 != 0) break;
            n /= 3;
        }
        return n == 1;
    }
}

238. 除自身以外陣列的乘積

中等

給你一個長度為 n 的整數陣列 nums,其中 n > 1,返回輸出陣列 output ,其中 output[i] 等於 nums 中除 nums[i] 之外其餘各元素的乘積。

示例:

輸入: [1,2,3,4]
輸出: [24,12,8,6]

提示:題目資料保證陣列之中任意元素的全部字首元素和字尾(甚至是整個陣列)的乘積都在 32 位整數範圍內。

說明:不要使用除法,且在 O(n) 時間複雜度內完成此題。

進階:
你可以在常數空間複雜度內完成這個題目嗎?( 出於對空間複雜度分析的目的,輸出陣列不被視為額外空間。)

class Solution {
    public int[] productExceptSelf(int[] nums) {
        int len = nums.length;
        int[] l = new int[len];
        int[] r = new int[len];
        l[0] = 1;
        for (int i = 1; i < len; i++) l[i] = l[i-1] * nums[i-1];
        r[len-1] = 1;
        for (int i = len-2; i >= 0; i--) r[i] = r[i+1] * nums[i+1];
        for (int i = 0; i < len; i++) l[i] *= r[i];
        return l;
    }
}

628. 三個數的最大乘積

簡單

給定一個整型陣列,在陣列中找出由三個陣列成的最大乘積,並輸出這個乘積。

示例 1:

輸入: [1,2,3]
輸出: 6

示例 2:

輸入: [1,2,3,4]
輸出: 24

注意:

  1. 給定的整型陣列長度範圍是[3,104],陣列中所有的元素範圍是[-1000, 1000]。
  2. 輸入的陣列中任意三個數的乘積不會超出32位有符號整數的範圍。
class Solution {
    public int maximumProduct(int[] nums) {
        Arrays.sort(nums);
        int len = nums.length;
        int a = nums[len-1] * nums[len-2] * nums[len-3];
        int b = nums[0] * nums[1] * nums[len-1];
        return a > b ? a : b;
    }
}

頻率排序

892,829,887,233,869,805,458,2,1121,423,483,469,149,365,640,535,782,1012,754,885,7,593,9,753,400