[Go version] Algorithm clearance village thirteenth level gold - number theory problems of digital mathematics (Greatest common divisor, prime number, Esperanza sieve, ugly number)

Topic: Rolling and dividing method (finding the greatest common divisor)

Topic link: LeetCode-1979. Find the greatest common divisor of an array
insert image description here

Analysis of ideas: tossing and dividing method (also called Euclidean algorithm)gcd(a,b) = gcd(b,a mod b)

The core part of the rolling and dividing method is: if r is the remainder of a ÷ b, then gcd(a, b)=gcd(b, r)

Complexity: Time complexity O ( n + log ( max ) ) O(n+log(max))O ( n+l o g ( max x )) , space complexityO ( 1 ) O(1)O(1)

Go code

func findGCD(nums []int) int {
    
    
    max, min := getMaxMin(nums)
    return getGcd(max, min)
}
// gcd求最大公约数
func getGcd(a int, b int) int {
    
    
    yu := 0
    for b != 0 {
    
    
        yu = a % b  //得到余数
        a = b       //根据辗转相除法,把被除数赋给除数
        b = yu      //余数赋给被除数
    }
    return a        //返回除数
}
func getMaxMin(nums []int) (max int, min int) {
    
    
    max, min = nums[0], nums[0]
    length := len(nums)
    for i:=1; i<length; i++ {
    
    
        if nums[i] > max {
    
    
            max = nums[i]
        }
        if nums[i] < min {
    
    
            min = nums[i]
        }
    }
    return
}

Question: Check if a number is prime

Idea analysis: To judge whether n is a prime number, you only need to test all possible factors from 2 to sqrtN + "6K +1/-1" rule

Complexity: Time complexity O ( sqrt ( n ) ) O(sqrt(n))O ( s q r t ( n )) , space complexityO ( 1 ) O(1)O(1)

Go code

func isPrimes(n int) bool {
    
    
    if n <= 1 {
    
    
        return false
    }
    if n <= 3 {
    
    
        return true
    }
    if n%2==0 || n%3==0 {
    
    
        return false
    }
    // 判断n是否是素数时,只需要测试 2 到 sqrtN 的所有可能因子
    // max := int(math.Pow(float64(n), 0.5))
    max := int(math.Sqrt(float64(n)))
    // 根据 "6K +1/-1" 规则
    for i:=5; i<=max; i+=6 {
    
    
        // i+2 正好是 "6K +1/-1" 中的一个值
        if n % i == 0 || n%(i+2) == 0 {
    
    
            return false
        }
    }
    return true
}

Subject: Esperanto sieve

Topic link: LeetCode-204. Counting prime numbers
insert image description here

Analysis of ideas: the idea of ​​Esperanza's sieve method, gradually eliminate the numbers that are not prime numbers

If x is a prime number, then the multiples of x greater than x, 2x, 3x,... must not be prime numbers.
insert image description here

Complexity: Time complexity O ( nloglogn ) O(n log log n)O ( n l o g l o g n ) , space complexityO ( n ) O(n)O ( n )

  • Time complexity analysis:
    • The number of iterations of the outer loop is n-2, which is O ( n ) O(n)O ( n ) times.
    • The number of iterations of the inner loop is in the case of a prime number, starting from i*i, increasing i each time until n. This is because multiples less than i have previously been marked as non-prime. The number of iterations of the inner loop is approximately n/i, where i is a prime number. Therefore, the total number of iterations is n/2 + n/3 + n/5 + ..., and this sum is O ( nloglogn ) O(n log log n)O ( n log log n ) . _ _ _ _

Go code

func countPrimes(n int) int {
    
    
    count := 0
    isNotPrimes := make([]bool, n)
    for i:=2; i<n; i++ {
    
    
        if !isNotPrimes[i] {
    
    
            count++
            for j:=i*i; j<n; j+=i {
    
    
                isNotPrimes[j] = true
            }
        }
    }
    return count
}

Or the following language is clearer, but O ( n ) O(n)O ( n ) time complexity

func countPrimes(n int) (count int) {
    
    
    isPrimies := make([]bool, n)
    for i, _ := range isPrimies {
    
    
        isPrimies[i] = true
    }
    for i:=2; i<n; i++ {
    
    
        // 从2开始已经把2的所有倍数标记为false,3也是,所以剩下的未标记的都是质数
        if isPrimies[i] {
    
    
            count++
            // 直接从i*i开始标记,因为2i,3i...这些数一定在i之前就被其他数的倍数标记过了,例如2的所有倍数,3的所有倍数等
            for j:=i*i; j<n; j+=i {
    
    
                isPrimies[j] = false
            }
        }
    }
    return
}

Topic: Judging whether it is an ugly number

Topic link: LeetCode-263. Ugly numbers
insert image description here

Idea analysis: cycle division 2 3 5 to determine whether the final value == 1

Complexity: time complexity O ( logn ) O(log n)O ( l o g n ) , space complexityO ( 1 ) O(1)O(1)

  • Time complexity: depends on the number of times n is divided by 2 3 5, since n is divided by at least 2 each time, the number of division operations will not exceed O ( logn ) O(log n)O(logn)

Go code

func isUgly(n int) bool {
    
    
    if n < 1 {
    
    
        return false
    }
    if n == 1 {
    
    
        return true
    }
    arr := [3]int{
    
    2,3,5}
    for _, v := range arr {
    
    
        for n%v == 0 {
    
    
            n = n/v
        }
    }
    return n == 1
}

Guess you like

Origin blog.csdn.net/trinityleo5/article/details/132454191