哈希表 
      
    
      
      
      
        字符串 
      
    
      
      
      
        排序 
      
    
      
      
      
        数组 
      
    
      
      
      
        计数 
      
    
   
  
    
      
       
     
  
  
    
      
    
    
      
       
     
  
    
题目描述 
现在有一个特殊的排名系统,依据参赛团队在投票人心中的次序进行排名,每个投票者都需要按从高到低的顺序对参与排名的所有团队进行排位。
排名规则如下:
    参赛团队的排名次序依照其所获「排位第一」的票的多少决定。如果存在多个团队并列的情况,将继续考虑其「排位第二」的票的数量。以此类推,直到不再存在并列的情况。 
    如果在考虑完所有投票情况后仍然出现并列现象,则根据团队字母的字母顺序进行排名。 
 
给你一个字符串数组 votes 代表全体投票者给出的排位情况,请你根据上述排名规则对所有参赛团队进行排名。
请你返回能表示按排名系统 排序后  的所有团队排名的字符串。
 
示例 1: 
输入: votes = ["ABC","ACB","ABC","ACB","ACB"]
输出: "ACB"
解释: 
A 队获得五票「排位第一」,没有其他队获得「排位第一」,所以 A 队排名第一。
B 队获得两票「排位第二」,三票「排位第三」。
C 队获得三票「排位第二」,两票「排位第三」。
由于 C 队「排位第二」的票数较多,所以 C 队排第二,B 队排第三。
 
示例 2: 
输入: votes = ["WXYZ","XYZW"]
输出: "XWYZ"
解释: 
X 队在并列僵局打破后成为排名第一的团队。X 队和 W 队的「排位第一」票数一样,但是 X 队有一票「排位第二」,而 W 没有获得「排位第二」。 
 
示例 3: 
输入: votes = ["ZMNAGUEDSJYLBOPHRQICWFXTVK"]
输出: "ZMNAGUEDSJYLBOPHRQICWFXTVK"
解释: 只有一个投票者,所以排名完全按照他的意愿。
 
 
提示: 
    1 <= votes.length <= 1000 
    1 <= votes[i].length <= 26 
    votes[i].length == votes[j].length for 0 <= i, j < votes.length 
    votes[i][j] 是英文 大写  字母 
    votes[i] 中的所有字母都是唯一的 
    votes[0] 中出现的所有字母 同样也  出现在 votes[j] 中,其中 1 <= j < votes.length 
 
解法 
方法一:计数 + 自定义排序 
对于每个候选人,我们可以统计他在每个排位上的票数,然后根据不同的排位依次比较票数,票数相同则比较字母。
时间复杂度 \(O(n \times m + m^2 \times \log m)\) ,空间复杂度 \(O(m^2)\) 。其中 \(n\)  是 \(\textit{votes}\)  的长度,而 \(m\)  是候选人的数量,即 \(\textit{votes}[0]\)  的长度。
Python3 Java C++ Go TypeScript Rust 
class   Solution : 
    def   rankTeams ( self ,  votes :  List [ str ])  ->  str : 
        m  =  len ( votes [ 0 ]) 
        cnt  =  defaultdict ( lambda :  [ 0 ]  *  m ) 
        for  vote  in  votes : 
            for  i ,  c  in  enumerate ( vote ): 
                cnt [ c ][ i ]  +=  1 
        return  "" . join ( sorted ( cnt ,  key = lambda  c :  ( cnt [ c ],  - ord ( c )),  reverse = True )) 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 class  Solution   { 
     public   String   rankTeams ( String []   votes )   { 
         int   m   =   votes [ 0 ] . length (); 
         int [][]   cnt   =   new   int [ 26 ][ m   +   1 ] ; 
         for   ( var   vote   :   votes )   { 
             for   ( int   i   =   0 ;   i   <   m ;   ++ i )   { 
                 ++ cnt [ vote . charAt ( i )   -   'A' ][ i ] ; 
             } 
         } 
         Character []   s   =   new   Character [ m ] ; 
         for   ( int   i   =   0 ;   i   <   m ;   ++ i )   { 
             s [ i ]   =   votes [ 0 ] . charAt ( i ); 
         } 
         Arrays . sort ( s ,   ( a ,   b )   ->   { 
             int   i   =   a   -   'A' ,   j   =   b   -   'A' ; 
             for   ( int   k   =   0 ;   k   <   m ;   ++ k )   { 
                 if   ( cnt [ i ][ k ]   !=   cnt [ j ][ k ] )   { 
                     return   cnt [ j ][ k ]   -   cnt [ i ][ k ] ; 
                 } 
             } 
             return   a   -   b ; 
         }); 
         StringBuilder   ans   =   new   StringBuilder (); 
         for   ( var   c   :   s )   { 
             ans . append ( c ); 
         } 
         return   ans . toString (); 
     } 
} 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 class   Solution   { 
public : 
     string   rankTeams ( vector < string >&   votes )   { 
         int   m   =   votes [ 0 ]. size (); 
         array < array < int ,   27 > ,   26 >   cnt {}; 
         for   ( const   auto &   vote   :   votes )   { 
             for   ( int   i   =   0 ;   i   <   m ;   ++ i )   { 
                 ++ cnt [ vote [ i ]   -   'A' ][ i ]; 
             } 
         } 
         string   s   =   votes [ 0 ]; 
         ranges :: sort ( s ,   [ & ]( char   a ,   char   b )   { 
             int   i   =   a   -   'A' ,   j   =   b   -   'A' ; 
             for   ( int   k   =   0 ;   k   <   m ;   ++ k )   { 
                 if   ( cnt [ i ][ k ]   !=   cnt [ j ][ k ])   { 
                     return   cnt [ i ][ k ]   >   cnt [ j ][ k ]; 
                 } 
             } 
             return   a   <   b ; 
         }); 
         return   string ( s . begin (),   s . end ()); 
     } 
}; 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 func   rankTeams ( votes   [] string )   string   { 
     m   :=   len ( votes [ 0 ]) 
     cnt   :=   [ 26 ][ 27 ] int {} 
     for   _ ,   vote   :=   range   votes   { 
         for   i ,   ch   :=   range   vote   { 
             cnt [ ch - 'A' ][ i ] ++ 
         } 
     } 
     s   :=   [] rune ( votes [ 0 ]) 
     sort . Slice ( s ,   func ( i ,   j   int )   bool   { 
         a ,   b   :=   s [ i ] - 'A' ,   s [ j ] - 'A' 
         for   k   :=   0 ;   k   <   m ;   k ++   { 
             if   cnt [ a ][ k ]   !=   cnt [ b ][ k ]   { 
                 return   cnt [ a ][ k ]   >   cnt [ b ][ k ] 
             } 
         } 
         return   s [ i ]   <   s [ j ] 
     }) 
     return   string ( s ) 
} 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 function   rankTeams ( votes :   string []) :   string   { 
     const   m   =   votes [ 0 ]. length ; 
     const   cnt :   number [][]   =   Array . from ({   length :   26   },   ()   =>   Array ( m   +   1 ). fill ( 0 )); 
     for   ( const   vote   of   votes )   { 
         for   ( let   i   =   0 ;   i   <   m ;   i ++ )   { 
             cnt [ vote . charCodeAt ( i )   -   65 ][ i ] ++ ; 
         } 
     } 
     const   s :   string []   =   votes [ 0 ]. split ( '' ); 
     s . sort (( a ,   b )   =>   { 
         const   i   =   a . charCodeAt ( 0 )   -   65 ; 
         const   j   =   b . charCodeAt ( 0 )   -   65 ; 
         for   ( let   k   =   0 ;   k   <   m ;   k ++ )   { 
             if   ( cnt [ i ][ k ]   !==   cnt [ j ][ k ])   { 
                 return   cnt [ j ][ k ]   -   cnt [ i ][ k ]; 
             } 
         } 
         return   a . localeCompare ( b ); 
     }); 
     return   s . join ( '' ); 
} 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 impl   Solution   { 
     pub   fn   rank_teams ( votes :   Vec < String > )   ->   String   { 
         let   m   =   votes [ 0 ]. len (); 
         let   mut   cnt   =   vec! [ vec! [ 0 ;   m   +   1 ];   26 ]; 
         for   vote   in   & votes   { 
             for   ( i ,   ch )   in   vote . chars (). enumerate ()   { 
                 cnt [( ch   as   u8   -   b'A' )   as   usize ][ i ]   +=   1 ; 
             } 
         } 
         let   mut   s :   Vec < char >   =   votes [ 0 ]. chars (). collect (); 
         s . sort_by ( |& a ,   & b |   { 
             let   i   =   ( a   as   u8   -   b'A' )   as   usize ; 
             let   j   =   ( b   as   u8   -   b'A' )   as   usize ; 
             for   k   in   0 .. m   { 
                 if   cnt [ i ][ k ]   !=   cnt [ j ][ k ]   { 
                     return   cnt [ j ][ k ]. cmp ( & cnt [ i ][ k ]); 
                 } 
             } 
             a . cmp ( & b ) 
         }); 
         s . into_iter (). collect () 
     } 
} 
 
 
 
 
  
  
  
    
    
    
    
      
  
    
      
  
     
   
  GitHub