程式設計題 攀爬字串

2021-08-07 12:03:53 字數 1960 閱讀 3824

給定乙個字串s1,將其遞迴地分割成兩個非空子字串,從而將其表示為二叉樹。

下面是s1 = "great"的乙個可能表達:

great

/ \

gr eat

/ \ / \

g r e at

/ \a t

在攀爬字串的過程中,我們可以選擇其中任意乙個非葉節點,然後交換該節點的兩個兒子。

例如,我們選擇了"gr"節點,並將該節點的兩個兒子進行交換,從而產生了攀爬字串"rgeat"

rgeat

/ \

rg eat

/ \ / \

r g e at

/ \a t

我們認為,"rgeat""great"的乙個攀爬字串.

類似地,如果我們繼續將其節點"eat""at"進行交換,就會產生新的攀爬字串"rgtae"

rgtae

/ \

rg tae

/ \ / \

r g ta e

/ \t a

同樣地,"rgtae"也是"great"的乙個攀爬字串。

給定兩個相同長度的字串s1s2,判定s2是否為s1的攀爬字串。

思路1由於二叉樹是遞迴的建立的,那麼我們就可以嘗試從遞迴的角度來解決這個問題。對於兩個字串樹treea和treeb,分別記其左右子樹為treea(b)_left,treea(b)_right,那麼可以得到如下關係: 

isscramble(treea, treeb) = isscramble(treea_left, treeb_left) && isscramble(treea_right, treeb_right) || 

isscramble(treea_left, treeb_right) && isscramble(treea_right, treeb_left)。 

就是把字串s1分割成s11和s12,把字串s2在同樣位置分割成s21和s22,如果s11與s21,s12與s22都為攀爬字串或者s11與s22,s12與s21為攀爬字串,那麼字串s1和s2就同為攀爬字串。

class solution 

return false;

}};

思路2還有一種解法是動態規劃,為什麼可以這樣說呢?因為發現判斷s1和s2是不是攀爬字串時用到的是s1子串和s2子串的資訊,即可以理解為用到了歷史資訊,所以可以考慮用動態規劃來解決。我們考慮狀態dp[i][j][len]代表從字串s1的i位開始,字串s2的第j位開始,長度為len的字串是不是攀爬字串。那麼根據之前的遞迴思路,我們可以寫出遞推關係: 

dp[i][j][len] = dp[i][j][k]&&dp[i+k][j+k][len-k] || dp[i][j+len-k][k] && dp[i+k][j][len-k]。1 <= k < len,k可以理解為將字串一分為二的那個位置。 

注意dp[i][j][k]這些儲存的歷史資訊,這裡我們要把len迴圈放在最外層。邊界情況就是len==1的情況,需要先單獨處理一下。

bool isscramble(string s1, string s2) 

}for (int len = 2; len <= n; len++) }}

}}

return dp[0][0][n];

}

攀爬字串

給定乙個字串s1,將其遞迴地分割成兩個非空子字串,從而將其表示為二叉樹。下面是s1 great 的乙個可能表達 great gr eat g r e at a t在攀爬字串的過程中,我們可以選擇其中任意乙個非葉節點,然後交換該節點的兩個兒子。例如,我們選擇了 gr 節點,並將該節點的兩個兒子進行交換...

攀爬字串 LintCode

給定乙個字串 s1,將其遞迴地分割成兩個非空子字串,從而將其表示為二叉樹。下面是s1 great 的乙個可能表達 在攀爬字串的過程中,我們可以選擇其中任意乙個非葉節點,然後交換該節點的兩個兒子。例如,我們選擇了 gr 節點,並將該節點的兩個兒子進行交換,從而產生了攀爬字串 rgeat 我們認為,rg...

程式設計題 關於字串

目錄 把字串轉換成整數 劍指歐肥兒 第乙個只出現一次的字元 劍指歐肥兒 左旋轉字串 劍指歐肥兒 字元流中第乙個不重複的字元 劍指歐肥兒 題目描述 將乙個字串轉換成乙個整數 實現integer.valueof string 的功能,但是string不符合數字要求時返回0 要求不能使用字串轉換整數的庫函...