leetcode - 552. Student Attendance Record II

算法系列博客之Dynamic Programming

動態規劃是和貪心算法比較相似的一種算法策略
      很多時候它們一般都遵從於某種線性的策略,使得整個邏輯和複雜度都看上去是線性的
但其二者有着本質的區別
      動態規劃實際上是在劃分子問題,子問題可以用同種方法進行再度拆解,湊巧劃分的過程大多數時候是線性的
      而貪心算法則是解決問題的步驟看似是一個線性過程,但每一步可以看作一個原子操作,不可拆解

本篇博客將運用動態規劃的思想來解決leetcode上552號問題


問題描述:

Given a positive integer n, return the number of all possible attendance records with length n, which will be regarded as rewardable. The answer may be very large, return it after mod 10^9 + 7.

A student attendance record is a string that only contains the following three characters:
     ‘A’: Absent.
     ‘L’ : Late.
     ‘P’ : Present.
A record is regarded as rewardable if it doesn’t contain more than one ‘A’ (absent) or more than two continuous ‘L’ (late).

題目的模型大致符合典型的線性求解思路,因而可以嘗試找出長度爲n的解與長度爲n-1,n-2等的依賴關係
題目中看似有三種字母可選,但是A和L都是有限制的

A最多隻能夠出現一個,那麼整個尋求答案的邏輯中就只有兩中可能:有1個A 或 無A

  • 有一個A的時候,A的位置只能有n種,而其左側和右側的兩個子串中就一定不會有A
    可能的結果數也就等於左側結果乘以右側結果,問題轉化爲無A情況的求解
  • 無A的時候,假設poss[i] 表示 長度爲 i 沒有A的可能結果數
    現在只需考慮L和P,顯然從有限制條件的L入手會比較方便,恰巧這個限制給我們提供了線性依賴關係
    即使得長度爲i 的串只可能有以下幾種結尾方式:
          ·   以 P    結尾:這種情況的可能數等於poss[i-1]
          ·   以 PL  結尾:這種情況的可能數等於poss[i-2]
          ·   以 PLL 結尾:這種情況的可能數等於poss[i-3]
    從而poss[i] = poss[i-1] + poss[i-2] + poss[i-3]
    得到的這個遞推式表示至少需要定義三個邊界值poss[1] = 2, poss[2] = 4
    餘下的邊界值考慮定義poss[0]還是poss[3]:
    長度爲3,以PLL結尾的可能數爲1,對應poss[0], 因而定義poss[0]是有意義的,此外以0作爲起始點額更加與計算機本身的特性貼合

回顧這個過程,當拋開A的影響之後,整個思路就變得非常的明朗清晰
而整個思路歷程也已經嚴謹的證明了這個算法的正確性和可行性
基於此再來實現代碼也好似非常的容易了

class Solution(object):
    def checkRecord(self, n):
        if n == 1:
            return 3

        poss = [1, 2, 4]
        for i in range(2, n):
            poss.append((poss[i] + poss[i-1] + poss[i-2]) % 1000000007)
        res = poss[n]
        for i in range(n):
            res = (res + poss[i] * poss[n-i-1]) % 1000000007
        return res

時間複雜度分析,兩次並行關係的規模爲n的循環,循環內部常數規模指令,因而O(n)
空間複雜度分析,空間上,用到了規模爲n的數組,因而也爲O(n)
實際上,得到的遞推式很多時候還可以通過數學方法歸納爲一個表達式,從而得到O(1)的高效率算法
但是,就這個題而言,因爲還需要計算有一個A的情況,所以需要存儲poss數組,也就必然需要進行線性循環了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章