1. 程式人生 > >LeetCode第87題(擾亂字串)

LeetCode第87題(擾亂字串)

原題如下:

給定一個字串 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” 的一個擾亂字串。

給出兩個長度相等的字串 s1 和 s2,判斷 s2 是否是 s1 的擾亂字串。

示例 1:

輸入: s1 = “great”, s2 = “rgeat” 輸出: true 示例 2:

輸入: s1 = “abcde”, s2 = “caebd” 輸出: false

這道題確實是比較坑的,因為他打上了動態規劃的標籤,但是說實話 ,我連最優子結構 都找不到。。。所以只能另尋它路,同時你需要注意題中的一句話!!!“我們可以挑選任何一個非葉節點,然後交換它的兩個子節點”

也就是說 任何一個大於等於2個size的串 都可以拆分成 2個部分!!! 比如 great 可以拆成 “g+reat” “gr+eat” “gre+at” “ grea+t ” 再從s2中挑選出 相同 size的串 來比較是否是擾亂子串 即可

根據上面的提示 一般都可以很快的寫出答案來,但是!!!!!!!你會發現時間複雜度達不到!!!(這個時候 你需要有以下思考, 1.我是否做了很多無用功(讓計算機計算了根本就沒有必要的部分) 2.如果1中我沒有做無用功,那麼說明這個演算法本身就有問題,我需要想其他的方法) 經過仔細觀察,你會發現 如果 s1 被拆成 ge+rat s2 被拆成 eag +rt 的時候 其實根本就沒有必要 去比較 rt是否是 ge的擾亂字串了!!!!!!直接就return false

程式碼如下:

vector<int> str_hash(string &s){
		vector<int>m(30); for (int i = 0; i <= m.size() - 1; i++)m[i] = 0;
		for (int i = 0; i <= s.size() - 1; i++){
			m[s[i] - 'a']++;
		}
		return m;
	}
bool bijiao(vector<int>&a, vector<int>&b){
		if (a.size() != b.size())return false;
		for (int i = 0; i <= a.size() - 1; i++){
			if (a[i] != b[i])return false;
		}
		return true;
	}
	bool isScramble(string &s1, string &s2) {
		if (s1.size() <= 0 || s2.size() <= 0) return false;
		if (s1.size() <= 1){
			if (s1[0] == s2[0])
				return true;
			else return false;
		}
		vector<int>s1_hash = str_hash(s1);
		vector<int>s2_hash = str_hash(s2);
		if (bijiao(s1_hash, s2_hash) == false) return false;
		for (int size = 1; size <= s2.size() - 1; size++){
			string s2_x = s2.substr(0, size), s2_y = s2.substr(size, s2.size() - size);
			string s1_x = s1.substr(0, size), s1_y = s1.substr(size, s1.size() - size);
			if (isScramble(s1_x, s2_x) && isScramble(s1_y, s2_y)) return true;
			else {
				s1_x = s1.substr(s1.size() - size, size); s1_y = s1.substr(0, s1.size() - size);
				if (isScramble(s1_x, s2_x) && isScramble(s1_y, s2_y)) return true;
			}
		}
		return false;
	}