日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Leetcode: Palindrome Partition I II

發布時間:2023/12/9 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Leetcode: Palindrome Partition I II 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

題目一, 題目二

?

?

思路

1. 第一遍做時就參考別人的, 現在又忘記了?做的時候使用的是二維動態規劃, 超時加超內存

?

2. 只當 string 左部分是回文的時候才有可能減少 cut

?

3. 一維動規. 令 cuts[i] 表示string[i, string.size()] 所需的切割數, 那么

狀態轉移方程為 cuts[i] = min(cuts[j]+1) j > i && string[i, j] is palindrome

時間復雜度上仍是 o(n*n), 但更新 cuts 的限制條件比較多了, cuts[i] 更新頻率較低?

?

代碼:

超時二維動規代碼

#include <iostream> #include <memory.h> using namespace std;int cuts[1000][1000]; int palindrom[1000][1000]; const int INFS = 0x3f3f3f3f; class Solution { public:int minCut(string s) {memset(cuts, 0x3f, sizeof(cuts));memset(palindrom, 0x3f, sizeof(palindrom));int curcuts = countCuts(s,0,s.size()-1);return curcuts;}int countCuts(string &s, int i, int j) {if(j <= i) return 0;if(isPalindrome(s,i,j))return (cuts[i][j]=0);if(cuts[i][j] != INFS)return cuts[i][j];int curcuts = INFS;for(int k = i; k < j; k++) {curcuts = min(curcuts, 1+countCuts(s,i,k)+countCuts(s,k+1,j));}return (cuts[i][j]=curcuts);}bool isPalindrome(string &s, int i, int j) {if(palindrom[i][j] == 1)return true;if(j <= i)return (palindrom[i][j] = true);if(palindrom[i][j] == 0)return false;return (palindrom[i][j] = (s[i]==s[j] && isPalindrome(s,i+1,j-1)));} };int main() {string str = "apjesgpsxoeiokmqmfgvjslcjukbqxpsobyhjpbgdfruqdkeiszrlmtwgfxyfostpqczidfljwfbbrflkgdvtytbgqalguewnhvvmcgxboycffopmtmhtfizxkmeftcucxpobxmelmjtuzigsxnncxpaibgpuijwhankxbplpyejxmrrjgeoevqozwdtgospohznkoyzocjlracchjqnggbfeebmuvbicbvmpuleywrpzwsihivnrwtxcukwplgtobhgxukwrdlszfaiqxwjvrgxnsveedxseeyeykarqnjrtlaliyudpacctzizcftjlunlgnfwcqqxcqikocqffsjyurzwysfjmswvhbrmshjuzsgpwyubtfbnwajuvrfhlccvfwhxfqthkcwhatktymgxostjlztwdxritygbrbibdgkezvzajizxasjnrcjwzdfvdnwwqeyumkamhzoqhnqjfzwzbixclcxqrtniznemxeahfozp";cout << str.size() << endl;cout << (new Solution())->minCut(str) << endl;return 0; }

  

優化后的一維動規

#include <iostream> #include <memory.h> using namespace std;int cuts[1500]; int palindrom[1500][1500]; const int INFS = 0x3f3f3f3f; class Solution { public:int minCut(string s) {memset(cuts, 0x3f, sizeof(cuts));memset(palindrom, 0x3f, sizeof(palindrom));int curcuts = countCuts(s,0,s.size()-1);return curcuts;}int countCuts(string &s, int i, int j) {if(j <= i) return 0;if(isPalindrome(s,i,j))return 0;if(cuts[i] != INFS)return cuts[i];int curcuts = INFS;for(int k = i; k < j; k++) {if(isPalindrome(s,i,k))curcuts = min(curcuts, 1+countCuts(s,k+1,j));}return (cuts[i]=curcuts);}bool isPalindrome(string &s, int i, int j) {if(palindrom[i][j] == 1)return true;if(j <= i)return (palindrom[i][j] = true);if(palindrom[i][j] == 0)return false;return (palindrom[i][j] = (s[i]==s[j] && isPalindrome(s,i+1,j-1)));} };int main() {string str = "bb";cout << str.size() << endl;cout << (new Solution())->minCut(str) << endl;return 0; }

  

I

第一題用動態規劃也是可以做的, 不過會比較麻煩(與Word Break類似)

這里用 dfs 加打印路徑, 比較直觀

int palindrom[1500][1500]; vector<vector<string> > res; class Solution { public:vector<vector<string>> partition(string s) {res.clear();memset(palindrom, 0x3f, sizeof(palindrom));vector<string> tmp;dfs(s, tmp, 0);return res;}bool isPalindrome(string &s, int i, int j) {if(palindrom[i][j] == 1)return true;if(j <= i)return (palindrom[i][j] = true);if(palindrom[i][j] == 0)return false;return (palindrom[i][j] = (s[i]==s[j] && isPalindrome(s,i+1,j-1)));}void dfs(string &s, vector<string> cur_vec, int depth) {if(depth == s.size()) {res.push_back(cur_vec);return;}for(int i = depth; i < s.size(); i ++) {if(isPalindrome(s, depth,i)) {cur_vec.push_back(s.substr(depth,i-depth+1));dfs(s, cur_vec, i+1);cur_vec.pop_back();}}} };

  

總結

以上是生活随笔為你收集整理的Leetcode: Palindrome Partition I II的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。