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. 下面给出代码:
输出为: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
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
相关文章推荐
- [LeetCode] String Reorder Distance Apart
- Leetcode: Rearrange String k Distance Apart
- [LeetCode] Rearrange String k Distance Apart 按距离为k隔离重排字符串
- Rearrange String k Distance Apart
- 【LeetCode 358】 Rearrange String k Distance Apart
- LeetCode Rearrange String k Distance Apart
- 微软2014实习生及校招秋令营技术类职位在线测试:1.String reorder
- String reorder
- 【微软2014实习生及秋令营技术类职位在线测试】题目1 : String reorder
- 微软2014实习生及秋令营技术类职位在线测试:String reorder
- 微软2014实习生招聘编程测试string reorder
- String reorder
- 微软2014实习生及秋令营技术类职位在线测试(题目1 : String reorder)
- 微软2014实习生及秋令营技术类职位在线测试第一题:String reorder
- 微软实习机试题 String reorder 的 Java 实现
- String reorder
- (2014微软实习生笔试题)1.String reorder
- 微软2014实习生及秋令营技术类职位在线测试(题目1 : String reorder)
- String reorder(一道自定义排序题)
- 2014微软实习生笔试题-String reorder