1. 程式人生 > >leetcode-506-Relative Ranks

leetcode-506-Relative Ranks

部分 過程 sco let desc 排列 IT find ==

題目描述:

Given scores of N athletes, find their relative ranks and the people with the top three highest scores, who will be awarded medals: "Gold Medal", "Silver Medal" and "Bronze Medal".

Example 1:

Input: [5, 4, 3, 2, 1]
Output: ["Gold Medal", "Silver Medal", "Bronze Medal", "4", "5"]
Explanation: The first three athletes got the top three highest scores, so they got "Gold Medal", "Silver Medal" and "Bronze Medal". 

For the left two athletes, you just need to output their relative ranks according to their scores.

Note:

  1. N is a positive integer and won‘t exceed 10,000.
  2. All the scores of athletes are guaranteed to be unique.

要完成的函數:

vector<string> findRelativeRanks(vector<int>& nums)

說明:

1、這道題給定一個vector,存放不同數值的分數,比如[2,4,3,5,1],輸出是[“4”,“silver medal”,“bronze medal”,“gold medal”,“5”]。前三名比較特殊,後面輸出數字的次序。

2、傳統思路快速處理,如下:

先對給定vector排序,然後叠代一遍排序後的vector,建立每個數跟排序的對應表。

最後對原本給定的vector,叠代一遍,輸出每個數對應的次序,1/2/3名特殊處理。

代碼如下:

    vector<string> findRelativeRanks(vector<int>& nums) 
    {
        vector<int>nums1=nums;//存儲一份副本
        sort(nums.begin(),nums.end(),greater<int>());//降序排列,改變nums的排序
        map
<int,int>m1;//建立數值和次序的對應表 for(int i=0;i<nums.size();i++) m1[nums[i]]=i+1; vector<string>res; for(int i=0;i<nums.size();i++)//對原本vector進行叠代 { if(m1[nums1[i]]==1) res.push_back("Gold Medal"); else if(m1[nums1[i]]==2) res.push_back("Silver Medal"); else if(m1[nums1[i]]==3) res.push_back("Bronze Medal"); else res.push_back(to_string(m1[nums1[i]])); } return res; }

上述代碼十分直觀明了,非常暴力的手段,可想而知實測……

23ms,beats 22.36% of cpp submissions。

3、改進:

我們先看看哪些步驟是必須的。排序是必須的,因為最後要輸出每個數值的次序。建立副本是必須的,因為排序必然改變原來的vector。

那我去掉建立map這個過程?去掉之後比如原本是[2,4,3,5,1],排完序是[5,4,3,2,1],我要找到5所在位置,更新值為"gold medal"?但這樣做就是一個雙重循環了。我們建立map,之後再插入也不過是兩個單重循環。

我們在做排序的時候可不可以記住這個數的位置,比如[2,4,3,5,1]我們簡化成[0,1,2,3,4],然後降序排列成[5,4,3,2,1],其實按照位置來說也就是[3,1,2,0,4]。這樣我們記住了大小,第三個數最大,第一個數第二大……也記住了它們的位置。

這是一種可以參考的方法,註意看下這部分的代碼實現。

代碼如下:

   vector<string> findRelativeRanks(vector<int>& nums) 
    {
        vector<int> rank;
        for(int i=0; i<nums.size(); ++i) rank.push_back(i);//插入位置0/1/2/3/4這樣子
        sort(rank.begin(), rank.end(), [&](int a, int b){return nums[a] > nums[b];});//按照原本數值降序排列

        vector<string> ranks(nums.size());//最終要返回的vector        
        for(int i=3; i<nums.size(); ++i)
        {
            ranks[rank[i]] = std::to_string(i+1);
        }
        
        if(nums.size() > 0) ranks[rank[0]] = "Gold Medal";//邊界情況
        if(nums.size() > 1) ranks[rank[1]] = "Silver Medal";
        if(nums.size() > 2) ranks[rank[2]] = "Bronze Medal";
        
        return ranks;
    }

上述代碼來源於leetcode用戶@kevin36,實測13ms,beats 92.55% of cpp submissions。

leetcode-506-Relative Ranks