#include <iostream>
using namespace std;
char f(const string& strSrc)
{
char ch = 0;
int count = 0;
for (int i = 0; i < strSrc.size(); ++i) // 第一次循坏找到出现次数可能大于 n/2的元素
{
if (0 == count)
{
ch = strSrc[i];
count = 1;
}
else
{
if (strSrc[i] == ch)
{
++count;
}
else
{
--count;
}
}
}
count = 0;
for (int i = 0; i < strSrc.size(); ++i) // 再循环一次确认该元素出现的次数大于 n/2
{
if (strSrc[i] == ch)
{
++count;
}
}
if (count >= strSrc.size() / 2)
{
return ch;
}
else
{
return 0;
}
}
int main()
{
string strSrc = "afaaafesafjeoisajfojaaaaaaaaaaaaaaaaaaaaaafejoisafjjfieohgoiasjfnasgieoafnaopjgieafesojfoesajf";
cout << f(strSrc) << endl;
return 0;
}
需求:从一个长度为n的字符串中找出现次数大于n/2的字符。时间复杂度控制在O(n)。空间复杂度要求是O(1)。
解读:count初始化成0,当count再次变成0时,前面的字符已经不重要了,只需要对后面的字符进行重复之前的步骤即可,这像一个递归的思想。因为当i 等于2m时,此时目标字符最多出现了m次,也就是说它在后面出现的次数仍然大于后面字符串长度的1/2。
举个例子:假如有很多诸侯国,每个国家都有一定的兵力,所有的兵战斗力相等,各诸侯国随机相互征战。若某个国家的兵力超过所有国家兵力总和的一半,那这仗不管什么打,最后还整下兵力的一定是它了。若每个国家的兵力都不超过所有国家兵力总和的一半,那最后谁输谁赢还不一定呢,得看交战顺序了。
需求:从一个长度为n的字符串中找出现次数大于n/k的字符。时间复杂度控制在O(n)。空间复杂度要求是O(1)。
思路:满足条件的字符串个数最多有k-1个。定义k-1个变量保存可能满足条件的字符,定义k-1个计数器。。。。。。。(文字描述好麻烦,还是用C++代码描述吧),代码实现如下:
#include <iostream>
using namespace std;
string f(const string& strSrc, int k) // 返回满足的字符串
{
char ch[1024] = {0};
int count[1024] = {0};
for (int i = 0; i < strSrc.size(); ++i) // 第一次循坏找到出可能满足的元素
{
for (int j = 0; j < k; ++j)
{
if (0 == count[j])
{
int flag = 0;
for (int a = 0; a < k; ++a)
{
if (ch[a] == strSrc[i])
{
count[a]++;
flag = 1;
break;
}
}
if (0 == flag)
{
ch[j] = strSrc[i];
count[j] = 1;
break;
}
}
else
{
if (strSrc[i] == ch[j])
{
count[j]++;
}
else
{
count[j]--;
}
}
}
}
string strRet;
for (int j = 0; j < k; ++j)
{
count[j] = 0;
for (int i = 0; i < strSrc.size(); ++i) // 再循环一次确认该元素出现的次数是否满足
{
if (strSrc[i] == ch[j])
{
++count[j];
}
}
if (count[j] >= strSrc.size() / k)
{
strRet += ch[j];
}
}
return strRet;
}
int main()
{
string strSrc = "1111111111111111111111111111111fjsoaeijfoeajfopaj3333333333333333333333333333333333";
cout << f(strSrc, 3) << endl;
return 0;
}
更准确的来说,这个算法的时间复杂度应该是 n*k , 但是k往往很小,所以也可以认为是n吧。
反思:通过这个程序反思自身,希望自己有收获时不要骄傲,因为可能是有运气的成分,失败也不要气馁,因为只有非常优秀才是一定成功。