Leetcode 初級演算法 動態規劃

2021-09-09 06:53:19 字數 3108 閱讀 1773

二級標題格式:[章節內題號] [題庫內題號] [題目標題]

這一章節學的不是很好…

我的思路:先想了乙個遞迴的解法 發現跑的非常慢 才意識到需要乙個動態規劃的解法…

遞迴 12s 巨慢

public

intclimbstairs

(int n)

動態規劃 全陣列

public

intclimbstairs

(int n)

return arr[n]

;}

public

intclimbstairs

(int n)

;for

(int i =

1; i < n; i++

)return ways[1]

;

更神奇的做法:利用斐波那契公式 複雜度可以降到o(log n)(為什麼不是o(1):因為取n次方的複雜度是o(log n) 通過遞迴的方式來求冪 平方求冪(快速冪)

另乙個更容易理解的解釋)

我的思路:每一步檢查當前值和最小值 如果當前值小於最小值 不僅要更新最小值 還要更新最大值… 換言之 最大值只會出現在最小值之後

public

intmaxprofit

(int

arr)

else

if(max-min>known)}}

return known;

}

其他思路:基本思路不變 但是只需要記錄兩個:minprice和maxprofit

每乙個陣列中的值肯定會更新兩個值中的乙個…

public

intmaxprofit

(int prices)

return maxprofit;

}

我的思路:第一反應是n2的解法 複雜度顯然太高 直接忽略

然後想到的是字首陣列 求sums 然後利用前一問的結果 這樣的複雜度是o(n)的 但是實現出來略有麻煩 不夠優雅… (坑:對於全部是負數的情況需要特判 從所有數里直接選乙個最大的)

分治法的思路沒想到…是對兩個端點分別二分嗎?

public

intmaxsubarray

(int

nums)

// judge always negative

if(allneg)

// use last problem's solution

int minpos=

0, maxpos=0;

int knowndist=

0, lastminpos=

0, lastmaxpos=0;

for(

int i=

1;i1;i++

)else

if(sums[i]

-sums[minpos]

>knowndist)

}return sums[lastmaxpos]

-sums[lastminpos]

;}

其他思路:我的做法並不是動態規劃… 動態規劃需要拆分出子問題

在這裡實際上子問題是求 a[0,i] 的最小值 用maxsubarray(int a, int i)表示 那麼就很好得到限制條件

maxsubarray(a, i) = maxsubarray(a, i - 1) > 0 ? maxsubarray(a, i - 1) : 0 + a[i];

然後就可以寫了…用乙個dp陣列即可…複雜度o(n)

// source: 

public

intmaxsubarray

(int

nums)

return max;

}

其他思路:分治法 複雜度 o(n logn) **

先把整個陣列分成左右兩半 那麼總的最大值=max(左邊最大,右邊最大,跨過中點的最大)

左右兩部分顯然都是子問題 直接遞迴就好 問題是跨過中點的最大如何計算:從中點開始 向左右兩側延伸 最後再拼起來…

遞迴表示式 t(n) = 2t(n/2) + θ(n) 複雜度 o(n logn)

我的思路:啊…沒想出來…

一開始的思路是貪心 但是這樣未必能保證全域性最優…

但是感覺沒法確定子問題…

find recursive relation

recursive (top-down)

recursive + memo (top-down)

iterative + memo (bottom-up)

iterative + n variables (bottom-up)

以這個題目為例子

第1步 主要問題是找出遞推式

我之前一直在從前向後找 但是實際上應該反過來從後向前

rob(i) = math.max( rob(i - 2) + currenthousevalue, rob(i - 1) )

然後可以很快完成2 3

然後從3到4 注意到memo[0]=max(arr[-2]+arr[0],arr[-1]), memo[1]=arr[1] max(arr[-1]+arr[1],arr[0]) (此處巨坑)

(備註 方便理解 arr[-2]=arr[-1]=0 )

然後的memo[2]就是按照遞推公式了

然後從4到5就很簡單了 因為每次實際上只需要保留兩個值 所以只需要乙個size=2的陣列就行了

最終的解決:

ublic int

rob(

int[

] nums)

;int cnt =2;

while

(cntreturn math.

max(sum[0]

,sum[1]

);}

其他人的解答

public

introb

(int

nums)

return prev1;

}

LeetCode探索初級演算法 動態規劃

今天在leetcode上做了幾個簡單的動態規劃的題目,也算是對動態規劃有個基本的了解了。現在對動態規劃這個演算法做乙個簡單的總結。動態規劃英文 dynamic programming,是求解決策過程最優化的數學方法,後來沿用到了程式設計領域。動態規劃的大致思路是把乙個複雜的問題轉化成乙個分階段逐步遞...

Leetcode初級演算法

不是很難的一道動態規劃的題,感覺做多了就記住了。class solution return dp n 此題想法就是,只要後面買的減去前面買的能大於0,就算在內,每次買完和max比較,大於max就記錄為max,如果買的sum小於0了,重新開始買,sum記為0 class solution if sum...

Leetcode 初級演算法02

了解的知識 1.空間複雜度 空間複雜度 space complexity 是對乙個演算法在執行過程中臨時占用儲存空間大小的量度。這樣子理解起來有點困難,我們又了解到當乙個演算法的空間複雜度為乙個常量,即不隨被處理資料量n的大小而改變時,可表示為o 1 舉兩個例子 a.陣列的隨機訪問就是o 1 b.鍊...