[デイリー]練習最長のフィボナッチ数列

免責事項:この記事はブロガーオリジナル記事です、続くBY-SAのCC 4.0を著作権契約、複製、元のソースのリンクと、この文を添付してください。
このリンク: https://blog.csdn.net/qq_20141867/article/details/82707122

タイトル説明

配列を指定して、最長のシーケンスを見つけ、シーケンスは、フィボナッチ数列を満たすことです

注意:
シーケンス場合 バツ 1 バツ 2 バツ n個 X_1、X_2、...、x_nに関する 以下の条件を満足し、それがフィボナッチ式に言われています。

  • N> = 3
  • すべてのiについて、2 <= Nであり+ バツ + バツ + 1 = X i + 2 X_I + X_ {I + 1} = X_ {I + 2}

アイデア:

この問題は、フォークを考えるようになった、常にフィボナッチ数列は、配列{1,1,2,3,5,8} ......順序に従って厳格でなければならないと思った、と後に限り、スタイルができていることを学びました。

方法:暴力アルゴリズム、Fの列の数は、各番号に、最初の2つの数値を生成し、Xは= [i]は、Y [j]がシーケンスの開始である=のみ次の桁P = Xを計算する必要があることを想定依存するためY、Pを+とそれに続く配列が存在するか否かを判定する。各更新X、Y \左矢印 Y、P。

class Solution(object):
    def lenLongestFibSubseq(self, A):
        ans = 0
        n = len(A)
        for i in range(n):
            for j in range(i+1, n):
                x, y = A[j], A[i] + A[j]
                length = 2
                while y in A[j+1: n]:
                    x, y = y, x + y
                    length += 1
                ans = max(ans, length)
        return ans if ans >= 3 else 0

この方法は、時間の複雑さがあり、3つのネストされたループを持っています O ( n 2 l o g m ) O(N ^ 2log ^ M) 、mはシーケンスAの最大値であります 以下のために厳密に増加するシーケンスは、迅速配列要素を保存Pの目標値が配列中に存在しているかどうかを判断するためにセットを使用することができ、時間の複雑さが低減され O ( n 2 ) O(n^2) 、ストリンジェントな条件「は配列に格納された目標値Pは、その後、ターゲットが後、yの値xを起動する必要がある場合」と増加保証することができます

方法2:動的計画。我々は、([I]、[J])([J]、[K])意志満足[k]は[J] [I] + =場合、ノードとみなされ、我々接続された2つのノード間。次いで、F [1,2,3,5,8,13]、完全なパスが存在することに対応する(1,2)→(2,3)→(3,5)→(5,8)の配列について→( 8、13)。

[I] [j]は([I]、[J])は、最後のノードの経路長であるDPは、現在値[k]は[J] [I] + =とき仮定、( [J]、[K])は、このパスに加え、経路長プラス1、すなわち、満たすことができます。
d p [ j ] [ k ] = d p [ i ] [ j ] + 1 DP [J] [K] = DP [I] [J] + 1 の場合 a [ k ] = a [ i ] + a [ j ] [k]は[I] + [j]を= k > j K> J
d p [ j ] [ k ] = 2 DP [J] [K] = 2 そうでない場合は

class Solution(object):
    def lenLongestFibSubseq(self, A):
    	# 建立倒排字典
        index = {x: i for i, x in enumerate(A)}
        longest = collections.defaultdict(lambda: 2)

        ans = 0
        for k, z in enumerate(A):
            for j in range(k):
                i = index.get(z - A[j], None)
                if i is not None and i < j:
                    cand = longest[j, k] = longest[i, j] + 1
                    ans = max(ans, cand)

        return ans if ans >= 3 else 0

この方法3は:非厳密に増加シーケンスの場合、重複する値は、例えば、[0,1,1,2]、単に表示された各位置のすべての値のコレクションを格納するので、デフォルトの辞書、添字dictのストレージを使用することはできません。

def lenLongestFibSubseq(A):
    import collections
    n = len(A)
    index = collections.defaultdict(list)
    for i in range(n):
        index[A[i]].append(i)
    longest = collections.defaultdict(lambda: 2)

    ans = 0
    for k, z in enumerate(A):
        for j in range(k):
            # 找到前面所有满足条件的数字下标
            i_index = index.get(z - A[j], [])
            if i_index:
                m = len(i_index)
                # 最近原则,取离j最近的下标
                for i in range(m-1, -1, -1):
                    if i_index[i] < j:
                        cand = longest[j, k] = longest[i_index[i], j] + 1
                        ans = max(ans, cand)
                        break
    return ans if ans >= 3 else 0

おすすめ

転載: blog.csdn.net/qq_20141867/article/details/82707122