周賽339。難得Q1的數字這麼大,搞到質數篩直接TLE,太誇張了。
聽說有不少人沒有把1當成質數吃了WA。說起來我的模板也沒有判斷到這點,趕緊去更新。

題目

輸入二維整數陣列nums。

求nums在對角線上最大質數。如果對角線上沒有質數,則回傳0。

注意:

  • 質數必須大於1,且不可被自己以外的正整數整除
  • 對角線指的是nums[i][i]或是nums[i][nums.length-i-1]的位置

解法

題目很良心的告訴我們斜角線的座標,只要遍歷對角線上的元素,如果是質數則更新答案。
篩選出質數表,之後每次質數檢查都是O(1)。但是這裡的nums[i][j]高達4*10^6,每次篩會超時,必須放到全域去。

時間複雜度O((MX log log MX) + N),其中MX為max(nums[i][j])。空間複雜度O(MX)。

MX=4*10**6
sieve=[True]*(MX+1)
sieve[0]=sieve[1]=False
for i in range(2,MX+1):
    if sieve[i]:
        for j in range(i*i,MX+1,i):
            sieve[j]=False

class Solution:
    def diagonalPrime(self, nums: List[List[int]]) -> int:
        N=len(nums)
        ans=0
        
        for i in range(N):
            for j in [i,N-1-i]:
                x=nums[i][j]
                if sieve[x]:
                    ans=max(ans,x)
                    
        return ans

這題應該比較適合暴力檢查是否為質數,畢竟判斷一次只要O(sqrt(x)),最多只要判斷600次而已。
直接寫一個判斷函數,只要x不為1,且無法被2~sqrt(x)的任一整數整除就是質數。

另外有個小加速點,先確定數字大於當前答案在去判斷質數,如果小於ans就不管了。

時間複雜度O(N*sqrt(MX)),其中MX為max(nums[i][j])。空間複雜度O(1)。

class Solution:
    def diagonalPrime(self, nums: List[List[int]]) -> int:
        N=len(nums)
        ans=0
        
        def is_prime(x):
            if x==1:
                return False
            for i in range(2,int(x**0.5)+1):
                if x%i==0:
                    return False
            return True
        
        for i in range(N):
            for j in [i,N-1-i]:
                x=nums[i][j]
                if x>ans and is_prime(x):
                    ans=x
                    
        return ans