c++ Testdome exercise关于重复播放列表的最快解决方案

daupos2t  于 2023-04-01  发布在  其他
关注(0)|答案(2)|浏览(142)

我试着在TestDome上做了一个关于发现播放列表是否有重复的练习(TestDome C++ Playlist
我试着用这种方式解决:

bool isRepeatingPlaylist()
{
   std::map<std::string, int> songs;
   Song* pSong = this;
    
   while (pSong != nullptr) {
       
     if (songs[pSong->name] > 0)
         return true;
       
     songs[pSong->name]++;
     
     pSong = pSong->nextSong;

   }
     
   return false;
}

反馈是我通过了4个测试用例中的3个。我没有通过的测试用例是关于性能的。你能帮助我改进吗?

gr8qqesn

gr8qqesn1#

第四个测试是“在大型播放列表上的性能测试”,当涉及到效率时,你不需要有序数据,你应该使用unordered_set〈〉或unordered_map〈〉。
map〈〉的搜索复杂度是O(log n),但在最坏的情况下,unordered_set〈〉或unordered_map〈〉的平均复杂度是O(1)到O(n)。
下面的代码通过了TestDome C++ Playlist的所有4个测试

bool isRepeatingPlaylist()
{

    std::unordered_set<std::string> playedSongs;
    Song *pSong = this;

    while (pSong != nullptr)
    {

        if (playedSongs.find(pSong->name) == playedSongs.end())
            playedSongs.insert(pSong->name);
        else
            return true;

        pSong = pSong->nextSong;
    }

    return false;
}

要使用它,只需添加#include<unordered_set>

ojsjcaue

ojsjcaue2#

该解决方案使用标准环路检测算法,并且还通过了所有测试:

bool isInRepeatingPlaylist()
{
    Song *p1 = this;
    Song *p2 = this;
    do {
      p1 = p1->nextSong;
      if(p2->nextSong != nullptr) {
        p2 = p2->nextSong->nextSong;
      } else {
        break;
      }
      
      if(p1 == p2) return true;
      
    } while(p1 != nullptr && p2 != nullptr);
    
    return false;
}

相关问题