給定乙個字串 s,將 s 分割成一些子串,使每個子串都是回文串。
返回 s 所有可能的分割方案。
示例:輸入: 「aab」
輸出:[
[「aa」,「b」],
[「a」,「a」,「b」]
]分析:
一種基礎方案是單個字元作為乙個子串;剩下的構造,只需進行合併操作即可。但這種自底向上的方案,並不好確定組合。
那直接進行劃分怎麼樣?以aab為例,
aab
/ \
a ab
| / \
a a b
在每層可以劃分len(str)次,每次劃分分為左右兩部分,若左右兩部分都是回文則記錄到l,r中,並分別遞迴下去,在遞迴中通過記錄在其lr中,返回前,對lr中的回文字串合併,然後返回;
如a是回文,加入l,ab不是,則r{},左側因為只有乙個字元所以不進入,右側遞迴,ab分成a,b因為都是回文加入到l2r2,返回前合併成,退回到ab處,即r,對lr組合,},返回到頂層;接著在第二個a處劃分,得到,},從這裡我們看到存在重複,可以在組合加入前檢查是否存在,實現過濾;最終,}。
aab
/ \
aa b
//超時,可以看到,該思路的不清晰,迷茫
//dfs最近練習的少,處理不順
func
partition
(s string)[
][]string
func
dfs(s string
)(r[
]string
)else
iflen
(s)==1}
}for i:=
1;i<
len(s)
;i++
l=(l,v...
) r=
(r,l)}}
}return r
}func
ispalindrome
(s string
)bool
else
}return
true
}
上邊dfs方法超時,如何解決呢,其實,我們可以減少乙個劃分,比如左端的劃分,因為最終加入的都是回文,它的可能只有s[0],s[0->1],…,s[0->n],只需要乙個迴圈判斷是否是回文就行,不是回文則看下乙個,加入的總是回文,接著對右邊部分遞迴進行相似判斷,這樣因為少了左右重複劃分,結果中也不會有重複資料,又減少了迴圈判斷;該方法很清晰。
package main
import
"fmt"
func
partition
(s string
)(r[
]string
)else
iflen
(s)==1}
}for i:=
1;i<=
len(s)
;i++
l=(l,v...
) r=
(r,l)
}if tmp==
nil||
len(tmp)==0
)}}}
return r
}func
ispalindrome
(s string
)bool
else
}return
true
}func
main()
131分割回文串
回溯 res tmp def ispalindrome self,s str 判斷是否是回文串 return s s 1 def dfs self,s str param s param index 初始為0 return if 0 len s 遞迴終止條件,在res中儲存tmp的複製值 tmp.c...
131 分割回文串
題目鏈結 與93題 恢復ip位址思路一致 給定乙個字串 s,將 s 分割成一些子串,使每個子串都是回文串。返回 s 所有可能的分割方案。示例 輸入 aab 輸出 aa b a a b class solution object def partition self,s type s str rtyp...
力扣131 分割回文串
題目 給定乙個字串 s,將 s 分割成一些子串,使每個子串都是回文串。返回 s 所有可能的分割方案。示例 輸入 aab 輸出 aa b a a b 分析 有點向之前求所有子串問題,採用dp動態規劃演算法,只是多加上了判斷是否為回文串,在 aab 一例中可以依次分析如下分割是否滿足回文串特性 a a ...