亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

redis源碼分析(七):集群--哨兵模式

標簽:
算法

webp

题目


矩阵形式

根据递推关系式,对二阶差分方程构造矩阵:

\begin{align} \left [ \begin{array} {cc} F(N)\\F(N-1) \end{array}\right ] & = \left [ \begin{array} {cc} F(N-1)+F(N-2)\\ F(N-1) \end{array}\right ] \\ & =\left [ \begin{array} {cc} 1&1\\1&0 \end{array}\right ] * \left [ \begin{array} {cc} F(N-1)\\F(N-2) \end{array}\right ] \end{align}

根据 \left [ \begin{array} {cc} F(N)\\F(N-1) \end{array}\right ] 的递推关系式, 可得:

\begin{align} \left [ \begin{array} {cc} F(N)\\F(N-1) \end{array}\right ] & = \left [ \begin{array} {cc} 1&1\\1&0 \end{array}\right ]^{N-1} * \left [ \begin{array} {cc} F(1)\\F(0) \end{array}\right ] \end{align}

import numpy as npimport mathdef climbingStairs_matrix(n):
    unit = np.array([[1, 1], [1, 0]])  
    target, result = n - 1, np.identity(2, int)  # target means the total index
    while target > 1:
        index, tmp = 1, unit
        times = int(math.log2(target))  # the iterations times
        while index <= times:
            tmp, index = np.dot(tmp, tmp), index + 1
        result = np.dot(tmp, result)
        target = target - 2 ** times
    result = np.dot(unit, result) if target == 1 else result
    result = np.dot(result, np.array([[1], [1]]))    return result[0][0]
  • 最好情况下

以求 M^N 值为例,若 2^k=N,则有如下分析:

若已知 M^{\frac N2},因为 M^N=M^{\frac N2} * M^{\frac N2},则只需要一次计算即可;

若已知 M^{\frac N4},因为 M^{\frac N2}=M^{\frac N4} * M^{\frac N4},则得出 M^N 值需要两次计算,首先计算出 M^{\frac N2},然后计算出 M^N;
...
...
...
若已知 M,则计算出 M^N 需要 k 次计算,即计算 M^N 值的时间复杂度为 O(log_2N)

即最好情况下矩阵运算的时间复杂度为 O(log_2N),空间复杂度为 O(1)

  • 最坏情况下

以求 M^N 值为例,若 2^k-1=N,则有:

M^N=M^{2^{k-1}} * M^{2^{k-1}-1}

由最好情况分析结论知,M^{2^{k-1}} 的计算次数为 k-1。若已知 M^{2^{k-1}-1},则得出 M^N 的值需要 (k-1)+1 次计算。

递推有:

M^{2^{k-1}-1}=M^{2^{k-2}} * M^{2^{k-2}-1}

由最好情况分析结论知,M^{2^{k-2}} 的计算次数为 k-2。若已知 M^{2^{k-2}-1},则得出 M^N 的值需要 (k-1)+1+(k-2)+1 次计算。
...
...
...

M^3=M^2*M

则得出 M^N 的值需要 (k-1)+1+(k-2)+1...+(1)+1=\frac {k^2}2+\frac k2-1 次计算。

即最坏情况下矩阵运算的时间复杂度为 O((log_2N)^2),空间复杂度为 O(1)


保留中间状态的矩阵形式

观察以上矩阵形式的代码可知,非最优场景下的计算过程存在重复运算,虽然通过对数形式降低了重复的次数,但依然存在计算能力的浪费。针对该情况,申请空间保留中间计算状态。

def climbingStairs_matrix(n):
    unit = np.array([[1, 1], [1, 0]])  # M represents the unit matrix
    arr, target, result = [unit], n - 1, np.identity(2, int)  # target means the total index
    while target > 1:
        index, tmp = 1, unit        times = int(math.log2(target))  # the iterations times
        if times >= len(arr):            while index <= times:
                tmp, index = np.dot(tmp, tmp), index + 1
                arr.append(tmp)        else:
            tmp = arr[times]
        result = np.dot(tmp, result)
        target = target - 2 ** times
    result = np.dot(unit, result) if target == 1 else result
    result = np.dot(result, np.array([[1], [1]]))    return result[0][0]

代码中增加 arr 数组保存中间的计算状态,其中 arr[i] 表示 unit^{2^i} 的值。该形式的矩阵运算时间复杂度为 O(log_2N),空间复杂度为 O(log_2N)

拓展形式


递归形式
def climbingStairs(n, m):
    if n == 0:        return 1
    stepSize, result = n if m >= n else m, 0
    for i in range(1, stepSize + 1):
        result += climbingStairs4(n - i, m)    return result


迭代形式
def climbingStairs(n, m):
    if n <= 1 or m == 1:        return 1
    stepSize = n if m >= n else m
    arr = [0] * stepSize
    arr[0], arr[1], index, tmp = 1, 1, 2, 1
    while index <= n:        if index > stepSize:
            tmp, arr[index % stepSize] = arr[index % stepSize], arr[(index - 1) % stepSize] * 2 - tmp        else:
            arr[index % stepSize] = arr[(index - 1) % stepSize] * 2
        index += 1
    return arr[(index - 1) % stepSize]

时间复杂度与步长为 1 ~ 2 时相同,为 。因为需要申请空间存储中间状态数据,所以空间复杂度为 O(M),其中 M 表示最大步长。



作者:zhipingChen
链接:https://www.jianshu.com/p/c93ed24932c2


點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消