題目鏈結
暴力解法為dfs搜尋,但是會tle,因此考慮動態規劃求解
定義f [i
][j]
f[i][j]
f[i][j
]表示到達格仔(i,
j)
(i, j)
(i,j
)的路徑總數
初始化首行和首列,如果該位置不可達則f[i
][j]
=0
f[i][j]=0
f[i][j
]=0,否則複製上一格仔的值
轉移方程:
f [i
][j]
=f[i
−1][
j]+f
[i][
j−1]
f[i][j]=f[i-1][j]+f[i][j-1]
f[i][j
]=f[
i−1]
[j]+
f[i]
[j−1
]如果該位置不可達
f [i
][j]
=0
f[i][j]=0
f[i][j
]=0
class
solution
:def
uniquepathswithobstacles
(self, g: list[list[
int]])
->
int:
r, c=
len(g)
,len
(g[0])
ifnot r or
not c:
return
0 f=[[
0for _ in
range
(c)]
for _ in
range
(r)]
f[0]
[0]=
0if g[0]
[0]else
1for i in
range(1
, c)
:if g[0]
[i]: f[0]
[i]=
0else
: f[0]
[i]=f[0]
[i-1
]for i in
range(1
, r)
:if g[i][0
]: f[i][0
]=0else
: f[i][0
]=f[i-1]
[0]for i in
range(1
, r)
:for j in
range(1
, c)
:if g[i]
[j]: f[i]
[j]=
0else
: f[i]
[j]=f[i-1]
[j]+f[i]
[j-1
]return f[r-1]
[c-1
]
題目鏈結
使用dfs求解, 將陣列拆分為0~9
的組合, 最高位不可用0
, 因此第0
輪迴圈需要從1
開始(確定高位),之後的迴圈從0
開始,如果組合值v>n
則return
.
class
solution
:def
lexicalorder
(self, n:
int)
-> list[
int]
: ans=
defdfs
(index, v)
:if v>n:
return
index=
0if index else
1for i in
range
(index,10)
: dfs(i+
1, v*
10+i)
dfs(0,
0)return ans
本題考慮使用字串動態規劃求解,或者使用trie+動態規劃求解.
定義f [i
]f[i]
f[i]
表示前i
ii的字元的最少匹配數,當在字典中搜尋到可以匹配以第i
ii個字元為結尾的單詞時,進行更新,此時有len(word)
個字元發生了匹配. 演算法時間複雜度o(n
m)
\mathcal(nm)
o(nm)f[i
]=mi
n(f[
i],f
[i−l
en(w
ord)
]f[i]=min(f[i], f[i-len(word)]
f[i]=m
in(f
[i],
f[i−
len(
word
)]
class
solution
:def
respace
(self, dictionary: list[
str]
, sentence:
str)
->
int:
n=len(sentence)
f=[0
for _ in
range
(n+1)]
for i in
range(1
, n+1)
: f[i]
=f[i-1]
+1for word in dictionary:
iflen
(word)
<=i and word==sentence[i-
len(word)
:i]:
f[i]
=min
(f[i]
, f[i-
len(word)])
return f[n]
trie+dp(tle),lc卡常,演算法時間複雜度o(n
2)
\mathcal(n^2)
o(n2
)
class
solution}}
return n-f[0]
;}// trie
struct node
;void
insert
(string word)
cur=cur-
>next[ch];}
if(!cur-
>word) cur-
>word=
true;}
intsearch
(string word)
if(cur-
>word)
return1;
else
return0;
} node *root;
};
本題思路和上題類似,只要設定初始化f[0]=true
以及改變一下轉移方程即可, 當i~i+len(word)
發生匹配時,f[i]|=f[i-len(word)]
進行轉移.
class
solution
:def
wordbreak
(self, s:
str, worddict: list[
str])-
>
bool
: n=
len(s)
f=[false
for _ in
range
(n+1)]
f[0]
=true
for i in
range(1
, n+1)
:for word in worddict:
iflen
(word)
<=i and s[i-
len(word)
: i]
==word:
f[i]
|=f[i-
len(word)
]return f[n]
演算法題解答
乙個二叉樹有2016個節點,最多有n個節點有2個子節點,求n並給出求導過程 給出一組一維座標如 ai,bi double型 程式設計算出覆蓋的長度,如 3,4 7,9 覆蓋長度為4 3 9 7 3 已知乙個一維陣列a,程式設計找出a i a i 1 a i 2 並計算時間複雜度 程式設計輸出任意正整...
A 演算法題解研究
從初始節點s到目標節點g s節點有相鄰的節點 f n g n h n g n 是移動代價 h n 是估計成本 第一步 計算s節點相鄰所有節點的f n 取最小的f n 的節點作為下乙個節點 假設s 下面是a,b節點 fa n ga n ha n 其中g是實際路徑 一般來講是指路徑上的值 h是估計路徑 ...
演算法題解整理
序號 型別解法1 解法2步驟 備註注意 1動態規劃 dp table的狀態轉移 確定 base case 變換目標 揹包問題,可拿出 第i個位置的值等於遍歷之前所有的dp值補上第i個位置到此位置的差值,取最大的值更新a i 子串行問題一般可用dp來解決 子串行的問題,一般用dp可以來解決 用乙個dp...