您的位置:首页 > 其它

String Reorder Distance apart

2012-08-12 16:57 513 查看
1. 题目:给定一个有小写字母组成的字符串,重组这个字符串,使相同字符之间的间隔至少为d。

  Input:{a,b,b}, distance=2

  output:{b,a,b}。

2. 个人认为这道题目很有难度。初看时不知如何下手。结合文章中给出的算法,具体算法如下:主体的算法思想是“贪心算法”。出现次数最多的字符被选中放入新字符串的优先级最高,如果这个字符不能被选中(因为距离的限制,比如上次选择了字符a,这次选择如果仍然a出现次数最多,但是却不能选a,因为如果要求距离为2,再次选择a,造成两个a相邻,那距离就为1了),那么我们选择下一个优先级最高的字符(并且这个字符的出现也要满足距离的要求,如果不满足,就接着选下一个优先级高的字符,以此类推;如果没有满足条件的字符,就说明出现了错误。比如给定字符aaaaa,要求重组字符距离为2,显然不存在这样的重组字符,返回error)。为了提高算法的效率,使用一些数组来存储信息。

3. 下面给出代码:

#include<iostream>
#include<cassert>

using namespace std;

int find_max(int freq[], bool excep[]) {
int max_i = -1;
int max = -1;
//找到出现次数最多的字母
//max记录出现次数最多的字母出现的次数
//max_i记录哪个字母出现次数最多
for (char c = 'a'; c <= 'z'; c++) {
if (!excep[c] && freq[c] > 0 && freq[c] > max) {
max = freq[c];
max_i = c;
}
}
return max_i;
}

void create(char* str, int d, char ans[]) {
int n = strlen(str);
int freq[256] = {0}; //记录每个字母出现次数
for (int i = 0; i < n; i++)
freq[str[i]]++;

int used[256] = {0};
for (int i = 0; i < n; i++) {
bool excep[256] = {false};
bool done = false;
while (!done) {
int j = find_max(freq, excep);
if (j == -1) {
cout << "Error!\n";
return;
}
excep[j] = true;
if (used[j] <= 0) {
ans[i] = j;
freq[j]--;
used[j] = d;
done = true;
}
}
for (int i = 0; i < 256; i++)
used[i]--;
}
ans
= '\0';
}
int main()
{
char* str="bbaaaccdd";
//char* str="aaaaaaadd";
int dis=3;
char ans[20];
create(str,dis,ans);
cout<<ans<<endl;
return 0;
}


输出为:abcadbacd

4. 代码分析:

  几个数组的作用:freq[256]:记录每个字母出现的次数,初始为0;used[256]:记录每个字母距离再次被选中的长度,例如,如果这次选择了字符a,就将used['a']设置为3,每次选择一个字符后,就将used数组中的每个数据减1,知道used['a']小于等于0,说明a再次出现在新数组中时就可以满足距离的要求;excep[256],每选中一个新字符就将这个字符的execp[]设置为true,for循环开始处将其置为false。

  第6行,函数find_max返回出现次数最多的字符。

  第28行,外层for循环每次选择一个字符加入到新字符串ans中。  

  第31行,while循环,选择一个合适的字符加入新的字符串。

  第33行,如果没有合适的字符即j==-1说明输入的字符不满足条件,返回error。

  第37行,将execp[]设置为true,即下次再选择时不再选择这个字符。

  第38行,如果used[]<=0,即满足条件说明,将选择的字符加入ans中,字符出现次数减一,used设为d,done变为true,退出while循环。如果不满足,while重新执行,选择新的字符。

  第45行,每次while执行完,即在ans中新加入了一个字符,那么所有字符的used计数减一。

5. 总结:这道题技巧性很强,我是写不出这样的代码的,以后努力加油吧!!!

参考文章:

http://www.leetcode.com/2010/05/here-is-another-google-phone-interview.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: