• LeetCode计数质数Swift


    统计所有小于非负整数 n 的质数的数量。

    示例 1:

    输入:n = 10
    输出:4
    解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7


    示例 2:

    输入:n = 0
    输出:0


    示例 3:

    输入:n = 1
    输出:0

    提示:

    0 <= n <= 5 * 106

    思路一:质数,只能被1和本身整除。

        //求n以内的质数
        func countPrimes1(_ n: Int) -> Int {
            if n < 3 {
                return 0
            }
            if n == 3 {
                return 1
            }
            var array:[Int] = [2]
            for i in 3 ... n - 1 {
                //默认是质数
                var flag = true
                for j in 2 ... i - 1 {
                    if i % j == 0 {
                        //能整除就是合数
                        flag = false
                        break
                    }
                }
                if flag == true {
                    array.append(i)
                }
            }
            print(array)
            return array.count
        }

    优化一:大于2的偶数肯定是合数,先过滤掉。然后除以2到i的平方根即可。

       //求n以内的质数
        func countPrimes4(_ n: Int) -> Int {
            if n < 3 {
                return 0
            }
            if n == 3 {
                return 1
            }
            if n == 4 || n == 5 {
                return 2
            }
            
            var array:[Int] = [2,3]
            for i in 5 ... n - 1 {
                if i % 2 == 0 {
                    //偶数肯定是合数
                    continue
                }
                //默认是质数
                var flag = true
                //如果一个合数,那它除了1和他本身一定还有别的约数,假如这个数是num,num=m*n 一定可以分解为两个整数相乘,设一个命题 ,num可以分解为两个数相乘且这两个数都大于num在平方根,m>sqrt(num) n>sqrt(num) 根据数学知识可以知道m*n>num 这与命题相反,所以命题是假的。所以合数一定至少有一个不大于sqrt(num)约数,只要找到这个数就可以了。
                let value = Int(sqrt(Double(i)))
                for j in 2 ... value {
                    if j % 2 == 0 {
                        //偶数肯定是合数
                        continue
                    }
                    if i % j == 0 {
                        //能整除就是合数
                        flag = false
                        break
                    }
                }
                if flag == true {
                    array.append(i)
                }
            }
            return array.count
        }

    思路二:性能很高

    1. 厄拉多塞筛法
    西元前250年,希腊数学家厄拉多塞(Eeatosthese)想到了一个非常美妙的质数筛法,减少了逐一检查每个数的的步骤,可以比较简单的从一大堆数字之中,筛选出质数来,这方法被称作厄拉多塞筛法(Sieve of Eeatosthese)。

    具体操作:先将 2~n 的各个数放入表中,然后在2的上面画一个圆圈,划去2的其他倍数;第一个既未画圈又没有被划去的数是3,将它画圈,划去3的其他倍数;现在既未画圈又没有被划去的第一个数 是 5,将它画圈,并划去5的其他倍数……依次类推,一直到所有小于或等于 n 的各数都画了圈或划去为止。这时,表中画了圈的以及未划去的那些数正好就是小于 n 的素数。

    分析:整个过程就是不停的画圈,最后没有被圈住的就是我们要的质数

    class Solution {
        func countPrimes(_ n: Int) -> Int {
            if n < 3 {
                return 0
            }
            var data = [Bool](repeating: true, count: n)
            var count = 0
    
            for i in 2..<n {
                if data[i] {
                  var j = i*2
                  while j<n {
                    data[j] = false
                    j+=i
                  }
                  count+=1
                }
            }
            return count
        }
    }
  • 相关阅读:
    为什么使用C#开发软件的公司和程序员都很少?
    使用Redis之前5个必须了解的事情
    这段代码为什么捕获不到异常呢?谁能给个解释,谢谢。
    git报错
    C# 常用类库(字符串处理,汉字首字母拼音,注入攻击,缓存操作,Cookies操作,AES加密等)
    你所不知道的 CSS 负值技巧与细节
    CSS 属性选择器的深入挖掘
    探秘 flex 上下文中神奇的自动 margin
    CSS 火焰?不在话下
    不可思议的纯 CSS 实现鼠标跟随效果
  • 原文地址:https://www.cnblogs.com/huangzs/p/14205614.html
Copyright © 2020-2023  润新知