题目
这题看起来不难,但实际上有挺多启发点的
错误解法:
这题有个理解误区,一开始以为是按照分数来排序。比如第一位得五分,第二位的四分这样,把所有的字符分数计算出来然后排序,于是就有了下面的错误解法
class Solution {
public:string rankTeams(vector<string>& votes) {
vector<pair<int,int>> scores(26,{
0,0});int n = votes[0].size();for(auto vote : votes){
for(int i=0;i<n;i++){
scores[vote[i]-'A'].first -= n-i;scores[vote[i]-'A'].second = vote[i]-'A';}}sort(scores.begin(),scores.end());string ans = "";for(auto score : scores){
if(!score.first) continue;ans += (score.second+'A');}return ans;}
};
解法1:
但再看题意,其实这样理解是错的。题目的意思是按照从前往后的比较顺序,有点像字典序,而不是以最后的分解过来比较这样。一旦按顺序某一位不相等,比较就会立即结束,而不是以某个字符的总得分来比较。
所以新的解法是这样的,建立一个二维数组,每一行代表的是某个字符的ranking统计,每一行的i位置的值代表该字符被投为第i名的次数。然后按照行跟行之间的相互大小关系来进行排序。但是由于排完序之后某行代表哪个字符没有办法确定,所以在每一行的最后添加改行代表字符的ascii值,这样排序后我们可以retrieve某一行代表哪个字符了。
然后自以为这题的关键就是自定义行跟行的比较,在C++里面也就是比较两个vector需要自定义operator,于是就有了下面的解法
class Solution {
static bool cmp(const vector<int>& a, const vector<int>& b){
for(int i=0;i<a.size();i++){
if(a[i] < b[i]){
return true;}else if(a[i] > b[i]){
return false;}}return false;}
public:string rankTeams(vector<string>& votes) {
vector<vector<int>> ranks(26,vector<int>(27,0));for(auto c : votes[0]){
ranks[c-'A'][26] = c;}for(auto vote : votes){
for(int i=0;i<vote.size();i++){
ranks[vote[i]-'A'][i] -= 1;}}sort(ranks.begin(),ranks.end(),cmp);string res;for(int i=0;i<votes[0].size();i++){
res += ranks[i][26];}return res;}
};
解法2:
解法1自然是能过得,但是后来看到网上有的解法居然不需要自定义operator???我之前是一直以为vector是没有default comparator的,但事实证明vector有默认的比较器,只不过是按照字典序来比较vector
参考:https://stackoverflow.com/questions/59668278/sorting-vector-of-vectors-without-comparator-or-lambda-function
class Solution {
public:string rankTeams(vector<string>& votes) {
vector<vector<int>> ranks(26,vector<int>(27,0));for(auto c : votes[0]){
ranks[c-'A'][26] = c;}for(auto vote : votes){
for(int i=0;i<vote.size();i++){
ranks[vote[i]-'A'][i] -= 1;}}sort(ranks.begin(),ranks.end());string res;for(int i=0;i<votes[0].size();i++){
res += ranks[i][26];}return res;}
};
C++版本这边注意char和int之间是有默认转化的,而且字符本来就是直接以ascii码的int值储存的。所以写起来很方便,python就要用ord()和chr()了
python版本:
python可以直接用字典代替vector,这样更节省空间,c++是因为unordered_map的value并不能是vector,所以用矩阵表示更方便
class Solution:def rankTeams(self, votes: List[str]) -> str:ranks = {
v:[0]*len(votes[0])+[v] for v in votes[0]}for vote in votes:for i,c in enumerate(vote):ranks[c][i] -= 1;tmp = list(votes[0])tmp.sort(key = lambda x:ranks[x])return "".join(tmp)