【數學】B051_四因數(枚舉 | 開平方)

一、題目描述

Given an integer array nums, return the sum of divisors of the integers in that array that have exactly four divisors.

If there is no such integer in the array, return 0.

Input: nums = [21,4,7]
Output: 32
Explanation:
21 has 4 divisors: 1, 3, 7, 21
4 has 3 divisors: 1, 2, 4
7 has 2 divisors: 1, 7
The answer is the sum of divisors of 21 only.

二、題解

嘗試一:暴力(超時)

代碼簡單。這次數據量爲 10510^5,有點大了。所以無腦行不通。

class Solution {
    public int sumFourDivisors(int[] nums) {
    int sum = 0;
    for (int n : nums) {
      if (check(n))
        sum += getSum(n);        
    }
    return sum;
  }
  private boolean check(int num) {
    int count = 0;
    for(int i=1; i<=num; i++){
      if(num%i == 0)
        count++;
      if (count > 4)
        return false;
    }
    return count == 4;
  }
  private int getSum(int num) {
    int sum = 0;
    for(int i=1; i<=num; i++){
      if(num%i == 0) {
        sum += i;
      }
    }
    return sum;
  }
}

嘗試二:sqrt(倒數第二個樣例不過)

算法

目標:求一個數的所有因數

  • 可以從 1 到 sqrt(num) + 1 枚舉。
  • 成立條件是:num % i == 0 && i != num / i

* 未知錯誤: 驗證倒數第二個樣例時出錯;

class Solution {
  public int sumFourDivisors(int[] nums) {
    int sum = 0;
    for (int n : nums) {
      if (check(n))
        sum += getSum(n);        
    }
    return sum;
  }
  private boolean check(int num) {
    int count = 0;
    for(int i=1; i <= (int)Math.sqrt(num); i++){
      if(num % i == 0 && i != num / i)
        count++;
      if (count > 2)
        return false;
    }
    return count == 2;
  }
  private int getSum(int num) {
    int sum = 0;
    for(int i=1; i<=num; i++){
      if(num%i == 0)
        sum += i;
    }
    return sum;
  }
}

嘗試三:更改條件

方法一、二的缺點:

  • 實際上不用先 check 再計算因數的和,直接在計算的時候記錄 count 的數量即可。

注意:和嘗試二是一個思路,但是就是多了這一句判斷:防止一些完全平方數摻和進來導致計算不精確,嘗試二就出現了這個問題。

if (count == 2 && sqrt * sqrt != n)
public int sumFourDivisors(int[] nums) {
    int res = 0;
    for (int n : nums) {
        res += find(n);
    }
    return res;
}
private int find(int n) {
    if (n <= 5) return 0;
    int sqrt = (int) Math.sqrt(n);
    int sum = 0;
    int count = 0;
    for (int i = 1; i <= sqrt; i++) {
        if (n % i == 0) {
            sum += i;
            sum += n / i;
            count++;
        }
        if (count > 2)  
        	return 0;
    }
    if (count == 2 && sqrt * sqrt != n)
        return sum;
    return 0;
}

複雜度分析

  • 時間複雜度:O(nlogn)O(n logn)
  • 空間複雜度:O(1)O(1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章