http://v.youku.com/v_show/id_XMTQzMDA0MDI1Ng==.html?spm=a2hzp.8253869.0.0
NO1 求一个字符串中输出最长的无重复字符的子串。
NO2 给定一个仅有小写字母构成的字符串,只能删除一些字符而不能修改字符串顺序,使得字符串中原先每种字符只出现一次并且字典序最小。
NO3 给定一个字符串,只包含左右括号( ),寻找最长的配对的子串并求其长度。比如”(()”最长配对是”()”,返回长度2;”)()()”最长配对子串是”()()”,返回长度4;
NO1 求一个字符串中输出最长的无重复字符的子串。
int LengthOfLongestSubString(string s)
{
int answer = 0;
vector
for (int i = 0, j = 0;; i++)
{
while (j < s.length() && !hash[s[j]])
{
hash[s[j++]] = true;
}
answer = max(answer, j - i);
if (j >= s.length())
{
break;
}
while (s[i] != s[j])
{
hash[s[i++]] = false;
}
hash[s[i]] = false;
}
return answer;
}
2)方法二(要求将最长的子数组res显示出来!!!)
#include
#include
#include
#include
#include
#include
using namespace std;
#define N 5 // N件宝贝
#define V 10 // C是背包的总capacity
vector
{
int answer = 0;
vector
vector
for (int i = 0, j = 0;; i++)
{
while (j < s.length() && !hash[s[j]])
{
hash[s[j++]] = true;
}
if ((j - i)>answer)
{
answer = j - i;
int jj = j, ii = i;
maxs.clear();
while (ii < jj)
{
maxs.push_back(s[ii++]);
}
}
if (j >= s.length())
{
break;
}
while (s[i] != s[j])
{
hash[s[i++]] = false;
}
hash[s[i]] = false;
}
return maxs;
}
int main() {
string s = "cdec";
vector
for (int i = 0; i < res.size(); i++)
{
cout << res[i] << " ";
}
system("pause");
return 0;
}
方法3(显示出数组来)
int maxStr(string str, vector
{
bool hashStr[256] = { false };
int len = str.length();
int maxRes = 0;
for (int i = 0,j=0; i < len;)
{
string tmp = "";
while ((hashStr[str[i]] != true)&&(i < len))
{
tmp += str[i];
hashStr[str[i]] = true;
i++;
}
tmp += '\0';
vec.push_back(tmp);
if ((i - j)>maxRes)
{
maxRes = (i - j);
res = tmp;
}
//maxRes = max(maxRes, i - j);
while (j != i)
{
hashStr[str[j++]] == false;
}
hashStr[str[j]] = false;
}
return maxRes;
}
int main() {
string str = "abccwsx";
vector
string res;
cout << maxStr(str, vec, res) << endl;
system("pause");
return 0;
}
NO2 给定一个仅有小写字母构成的字符串,只能删除一些字符而不能修改字符串顺序,使得字符串中原先每种字符只出现一次并且字典序最小。
方法1 贪心的思路
string removeDuplicateLetters(string s)
{
vector
vector
for (int i = 0; i < s.length(); i++)
{
++num[s[i]-'a'];
}
string answer = "";
for (int i = 0, last = 0; i < s.length();)//挨个i判断是否要加到answer里面
{
int c = s[i] - 'a';
if ((num[c] == 1) && (!in[c]))//如果只剩下最后一次并且没有在answer里面,那么就必需需要加到answer里面了
{
int x = -1;//x就是最小的字母
for (int j = last; j <= i; ++j)//如果字符串前面有更小的字符没有加到answer里面,那就找出字典序最小的字母s[x]。
{
if ((!in[s[j] - 'a']) && ((x < 0) || (s[j] < s[x])))
{
x = j;
}
}
answer += s[x];
in[s[x] - 'a'] = true;
if (s[x] == s[i])
{
++i;
}
last = x + 1;
}
else
{
--num[c];
++i;
}
}
return answer;
}
方法2,利用堆栈结构,时间复杂度为o(n)
string removeDuplicateLetters(string s)
{
vector
vector
stack
for (int i = 0; i < s.length(); i++)
{
++num[s[i]-'a'];//确定每个字母的出现次数
}
string answer = "";
for (int i = 0, last = 0; i < s.length();++i)
{
int c = s[i] - 'a';
--num[c];//判断第i个字符,先要将其出现次数减去1
if (!in[c])
{
while ((!st.empty()) && (st.top()>s[i]) && (num[st.top() - 'a']))//stack结构跟第i个字符比较,如果stack的头要大于第i个字符,那么就pop
{
in[st.top() - 'a'] = false;
st.pop();
}
st.push(s[i]);
in[c] = true;
}
}
for (; !st.empty(); st.pop())
{
//answer += st.top();
answer = st.top() + answer;//因为是反着,所以注意加法的前后顺序!!
}
return answer;
}
NO3 给定一个字符串,只包含左右括号( ),寻找最长的配对的子串并求其长度。比如”(()”最长配对是”()”,返回长度2;”)()()”最长配对子串是”()()”,返回长度4;
int GetLongestMatch(string inputStr) {
int maxLength = 0; //记录最长的括号匹配长度
int deep = 0;
int start = -1;
//适合处理右括号数大于左括号数
for (int i = 0; i < inputStr.length(); i++) {
char c = inputStr.at(i);
if (c == '(') {
deep++;
}
else {
deep--;
if (deep == 0) {
maxLength = maxLength < (i - start) ? i - start : maxLength;
}
//右括号数大于左括号数 不连续 重新计数
if (deep < 0){
start = i;
deep = 0;
}
}
}
deep = 0;
start = inputStr.length();
//适合处理左括号数大于右括号数
for (int i = inputStr.length() - 1; i >= 0; i--) {
char c = inputStr.at(i);
if (c == ')') {
deep++;
}
else {
deep--;
if (deep == 0) {
maxLength = maxLength < (start - i) ? start - i : maxLength;
}
else if (deep < 0) {
deep = 0;
start = i;
}
}
}
return maxLength;
}
NO 4 仅由三个字母abc构成字符串,且字符串要求人以三个相邻元素不能相同,如acccba不合法,accbbaa合法。求满足长度为n的,且满足上述条件的字符串的个数有多少?
假定不考虑整数溢出,要求时间空间复杂度不高于O(N)
http://v.youku.com/v_show/id_XMTM5MDUxNDU1Mg==.html?spm=a2hzp.8253869.0.0
动态规划思路!!
#define INT_MAX 3000
int dp[INT_MAX][INT_MAX] = { 0 };
int ThreeMax(int n)
{
dp[1][1] = 0;
dp[1][0] = 3;
for (int i = 2; i <= n; i++)
{
dp[i][0] = 2 * dp[i - 1][0] + 2 * dp[i - 1][1];//dp[i][0]代表前i个字符串最后两个字符不相同;dp[i][1]代表前i个字符串最后两个字符相同
dp[i][1] = dp[i - 1][0] + 0 * dp[i - 1][1];
}
return dp[n][0] + dp[n][1];
}
所以方法改进为如下,降低了空间复杂度!
int ThreeMax2(int n)
{
int dp1 = 0;
int dp0 = 3;//dp0代表前i个字符串最后两个字符不相同;dp1代表前i个字符串最后两个字符相同
for (int i = 2; i <= n; i++)
{
int tempdp0 = dp0;
int tempdp1 = dp1;
dp0 = 2 * tempdp0 + 2 * tempdp1;
dp1 = tempdp0 + 0 * tempdp1;
}
return dp0 + dp1;
}