【问题标题】:Why is vector<vector<int>> slower than vector<int> []?为什么 vector<vector<int>> 比 vector<int> [] 慢?
【发布时间】:2023-01-20 21:14:52
【问题描述】:

我试图解决 leetcode323。我的代码和解决问题的方法与官方答案基本相同。唯一的区别是我使用的是 vector<vector> 而官方答案使用 vector [] 来保留每个节点的邻居。当我使用 vector [] 时,系统接受了我的回答。使用 vector [] 比使用 vector<vector> 有什么优势吗?我把我的代码和官方的解决方案代码放在下面。非常感谢你提前。

"MY CODE"
class Solution {
    public :
    void explore(vector<bool> & visited,vector<int> nei[],int cur){
        visited[cur]=true;
        for(int i=0;i<nei[cur].size();i++){
            if(!visited[nei[cur][i]]){
                explore(visited,nei,nei[cur][i]);
            }
        }
    }
    
public:
    int countComponents(int n, vector<vector<int>>& edges) {
        vector<bool> visited(n);
       vector<vector<int>> neighbors(n);
        int count=0;
        for(int i=0;i<edges.size();i++){
            neighbors[edges[i][0]].push_back(edges[i][1]);
             neighbors[edges[i][1]].push_back(edges[i][0]);
        }
        for(int j=0;j<n;j++){
            if(!visited[j]){
                count++;
                explore(visited,neighbors,j);
            }
        }
        return count;

    }
};
"OFFICIAL SOLUTION"
class Solution { 
public: void dfs(vector<int> adjList[], vector<int> &visited, int src) { 
visited[src] = 1;    

for (int i = 0; i < adjList[src].size(); i++) {
        if (visited[adjList[src][i]] == 0) {
            dfs(adjList, visited, adjList[src][i]);
        }
    }
}

int countComponents(int n, vector<vector<int>>& edges) {
    if (n == 0) return 0;
  
    int components = 0;
    vector<int> visited(n, 0);
    vector<int> adjList[n];

    for (int i = 0; i < edges.size(); i++) {
        adjList[edges[i][0]].push_back(edges[i][1]);
        adjList[edges[i][1]].push_back(edges[i][0]);
    }
    
    for (int i = 0; i < n; i++) {
        if (visited[i] == 0) {
            components++;
            dfs(adjList, visited, i);
        }
    }
    return components;
}
};

"MY CODE"

【问题讨论】:

  • 当你在 LeetCode 论坛上问这个问题时,你得到了什么答案?是否提到官方解决方案不是有效的标准 C++ 代码?
  • 坏消息:您被无数编码挑战/谜题诈骗网站之一骗了。他们通过提供神秘的编码难题来利用想要学习 C++ 的人,并承诺您不需要通过一本好的教科书来学习和学习 C++,只需做一堆毫无意义的编码难题。每个人最终都会意识到,这些毫无意义的编码难题是在浪费时间,从中也没有什么可学的。但只有在花了很多时间去做之后。而且没有什么可显示的。
  • 您是否尝试分析代码?
  • Offtopic:leetcode 上的性能测量很糟糕。我见过相同的代码运行多次时最快和最慢运行之间的因素是3
  • 任务描述隐藏在付费专区后面。请至少提供输入限制。

标签: c++ algorithm graph-theory depth-first-search


【解决方案1】:

数组具有固定大小,向量具有动态大小。仅这一点并不能解释不同的性能,而是意味着它们适用于非常不同的用例。

但是,以减慢程序速度的方式使用 vector 更容易。当您推送元素并且新大小大于容量时,向量会重新分配。为了公平比较,您可以使用固定大小的向量,或者至少预先保留足够的容量,这样就不会发生重新分配。那么预计不会有太大差异。

您的大多数向量从大小 0 开始,我看不到 reserve 或类似的。仅推送单个元素会导致最糟糕的重新分配情况。

PS:出于不同的原因,嵌套向量也不那么流行。与其他标准容器(例如std::list)相比,std::vector 的一大优势是它的数据局部性。它的元素存储在连续的内存中。嵌套向量中最里面的元素不连续。不过,这与您的比较无关,因为在这两种情况下都存在一定程度的间接性。

【讨论】:

    猜你喜欢
    • 2021-11-07
    • 2020-07-15
    • 1970-01-01
    • 2020-12-27
    • 1970-01-01
    • 2022-08-07
    • 1970-01-01
    • 2019-09-06
    • 2016-11-11
    相关资源
    最近更新 更多