赞
踩
如果字符串中不含有任何 ‘aaa’,‘bbb’ 或 ‘ccc’ 这样的字符串作为子串,那么该字符串就是一个「快乐字符串」。
给你三个整数 a,b ,c,请你返回 任意一个 满足下列全部条件的字符串 s:
s 是一个尽可能长的快乐字符串。 s 中 最多 有a 个字母 ‘a’、b 个字母 ‘b’、c 个字母 ‘c’ 。 s 中只含有
‘a’、‘b’ 、‘c’ 三种字母。 如果不存在这样的字符串 s ,请返回一个空字符串
其中,0 <= a, b, c <= 100
a + b + c > 0""。
题解:根据本题的题意,很容易想到了深度优先搜索的算法,即dfs+剪枝,此时的算法时间复杂度应该为O(3^max(a,b,c))但是很遗憾,由于参数a,b,c的范围使得该算法的执行时间较慢,导致最终结果为TLE。
代码为:
class Solution { public: string ans; int Max; string x; int num[3]; string longestDiverseString(int a, int b, int c) { map<char, int> s; s['a'] = 1; s['b'] = 1; s['c'] = 1; Max = 0; ans = ""; x = ""; num[0] = a; num[1] = b; num[2] = c; getLong(s,-1); return ans; } void getLong(map<char, int> s,int alpha) { int i; if (s['a'] == 3) { if (Max < x.length()) { Max = x.length()-1; ans = x.substr(0,x.length()-1); } return; } if (s['b'] == 3) { if (Max < x.length()) { Max = x.length() - 1; ans = x.substr(0, x.length() - 1); } return; } if (s['c'] == 3) { if (Max < x.length()) { Max = x.length() - 1; ans = x.substr(0, x.length() - 1); } return; } for (i = 0; i < 3; i++) if (num[i] != 0) break; if (i == 3) { Max = x.length(); ans = x; return; } for (int i = 0; i < 3; i++) { if (num[i] > 0) { num[i]--; if (x.length() != 0 && x[x.length() - 1] - 'a' == i) s['a' + i]++; else if (x.length() != 0) { s['a' + i] = 1; } x += 'a' + i; getLong(s,i); x = x.substr(0, x.length() - 1); if (x.length() != 0 && x[x.length() - 1] - 'a' == i) s['a' + i]--; num[i]++; } } } };
执行结果为:
最后发现,这并不是一道dfs,而是一道贪心!!!
可以先看本题的题目条件:
而最终所需要得到的结果则是最长的字符串,因此很容易可以想到贪心策略:
个数较少的字母用于当做隔离字母,个数较多的字母优先排列;如果发现当前的字母个数超过了3个,则跳过当前字母,直到找到当前的可以添加的字母为止;若已经找不到当前可以添加的字母,则退出。
代码为:
class Solution { public: class mycomp2 { public: bool operator() (pair<char, int> a, pair<char, int> b) { return (a.second > b.second); } }; string longestDiverseString(int a, int b, int c) { string ans; vector<pair<char, int>> s = { {'a',a},{'b',b},{'c',c} }; while (1) { bool flag = false; sort(s.begin(), s.begin()+s.size(), mycomp2()); for (vector<pair<char, int>>::iterator it = s.begin(); it != s.end(); it++) { int m = ans.size(); char ch = (*it).first; int freq = (*it).second; if (freq <= 0) break; if (m >= 2 && ans[m - 2] == ch && ans[m - 1] == ch) continue; ans.push_back(ch); flag = 1; (*it).second--; break; } if (!flag) break; } return ans; } };
最终运行结果为:
采用贪心,则时间复杂度大大降低,主要的时间是在排序上,若采用sort函数,则时间复杂度为O((a+b+c)×ClogC)。
总览这道题,发现采用暴力算法并没有很好的完成这道题,很容易TLE;还是需要多多锻炼贪心或者dp的逻辑思维哇!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。