欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > 5.17 note

5.17 note

2025/5/18 7:58:14 来源:https://blog.csdn.net/2301_80171004/article/details/148019916  浏览:    关键词:5.17 note

反转链表

递归法
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(!head) return NULL;
        if(!head->next) return head;


        ListNode * newHead = reverseList(head->next); //走到最后,再实现翻转


        head->next->next = head;
        head->next = NULL; //置空
        return newHead;
    }
};

连通分量

#include <vector>
#include <unordered_map>
#include <functional>
using namespace std;

class Solution {
public:
    int countCompleteComponents(int n, vector<vector<int>>& edges) {
        vector<int> parent(n); // 节点数为n,初始化父数组大小为n
        vector<int> size(n, 1); // 记录每个连通分量的节点数
        unordered_map<int, int> edgeCount; // 记录每个连通分量的边数

        // 初始化并查集
        for (int i = 0; i < n; ++i) {
            parent[i] = i;
        }

        function<int(int)> find = [&](int idx) {
            if (parent[idx] != idx) {
                parent[idx] = find(parent[idx]);
            }
            return parent[idx];
        };

        auto unionSet = [&](int x, int y) {
            int root1 = find(x);
            int root2 = find(y);
            if (root1 != root2) {
                // 合并时小集合并到大集合(按秩合并优化)
                if (size[root1] < size[root2]) swap(root1, root2);
                parent[root2] = root1;
                size[root1] += size[root2]; // 合并后节点数累加
            }
        };

        // 处理所有边,构建并查集并统计边数
        for (const auto& e : edges) {
            int u = e[0], v = e[1];
            unionSet(u, v); // 合并节点
            int root = find(u); // 找到共同根节点
            edgeCount[root]++; // 根节点对应的边数+1(无向边每条会被处理两次,后续需除以2)

        }

        // 统计完全连通分量数量
        int result = 0;
        unordered_set<int> roots; // 记录所有根节点

        // 先收集所有根节点
        for (int i = 0; i < n; ++i) {
            roots.insert(find(i));
        }

        // 检查每个根节点对应的连通分量是否为完全图
        for (int root : roots) {
            int componentSize = size[root];
            int totalEdges = edgeCount[root]; // 无向边实际边数需除以2(每条边被记录两次)
            // 完全图边数公式:n*(n-1)/2,其中n是节点数
            if (componentSize * (componentSize - 1) / 2 == totalEdges) {
                result++;
            }
        }

        return result;
    }
};
 

函数包装器 function

  • -  function :给函数贴一个“类型标签”,明确函数的输入输出格式。
  • -  lambda :快速写一个没有名字的小函数,随用随写。

- 作用:在 C++ 中实现类似 Python 嵌套函数的效果,让代码更模块化、更简洁。

可以简单记住:它们就是 “临时定义的小工具函数”,专门用来辅助解决当前问题,用完就“丢弃”,不用单独命名和管理。

 

复习并查集

#include <vector>
using namespace std;

class Solution {
public:
    int findCircleNum(vector<vector<int>>& isConnected) {
        int cities = isConnected.size();
        vector<int> parent(cities);
        for (int i = 0; i < cities; ++i) { // 初始化父节点数组
            parent[i] = i;
        }

        function<int(int)> find = [&](int idx) { // 定义路径压缩的find函数
            if (parent[idx] != idx) {
                parent[idx] = find(parent[idx]);
            }

            return parent[idx];
        };

        auto unionSet = [&](int x, int y) { // 定义合并集合的union函数
            int root1 = find(x);
            int root2 = find(y);
            if (root1 != root2) {
                parent[root2] = root1; // 合并方式采用将root2的父节点设为root1
                //<---------

            }
        };

        // 遍历所有城市对,合并连通的城市
        for (int i = 0; i < cities; ++i) {
            for (int j = i + 1; j < cities; ++j) {
                if (isConnected[i][j] == 1) {
                    unionSet(i, j);
                }
            }
        }

        // 统计根节点数量(连通分量数)
        int provinces = 0;
        for (int i = 0; i < cities; ++i) {
            if (parent[i] == i) {
                provinces++;
            }
        }
        return provinces;
    }
};

连通图

无向图,所以可以写的很简单。

遍历i查找,!check[i](因为无向 所以一维标记),然后对未标记的dfs j check[j]查找连通,记录ret

class Solution {

     vector<vector<int>> g;

     vector<int> check;

     int m,n,ret=0;

     //利用了 无向图

public:

    int findCircleNum(vector<vector<int>>& isConnected) 

    {

      this->g=isConnected;

      m=isConnected.size();

      n=isConnected[0].size();

      check.resize(n);

      

      for(int i=0;i<m;i++)

      {

          if(!check[i])

          {

              check[i]=true;

              dfs(i);

              ret++;

          }

      }

      return ret;

    }

 

    void dfs(int i)

    {

        for(int j=0;j<n;j++)

        {

            if(g[i][j] && !check[j])

            {

                check[j]=true;

                dfs(j);

            }

        }

    }

};

完全连通分量 建图

class Solution {
public:

    vector<vector<int>> g;
    vector<int> st;
    int v, e;

    int countCompleteComponents(int n, vector<vector<int>>& edges) {
        g.resize(n);
        st.resize(n);
        for(vector<int>& edge : edges){
            g[edge[0]].push_back(edge[1]);
            g[edge[1]].push_back(edge[0]);
        }
        int ans = 0;
        for(int i = 0; i < n; i ++){
            if(!st[i]){

                v = 0;
                e = 0;
                dfs(i);
                ans += (e == v * (v - 1));
            }
        }
        return ans;
    }
    void dfs(int x){
        st[x] = true;
        v ++;
        e += g[x].size();
        for(int& y : g[x]){
            if(!st[y]) dfs(y);

        }
    }
};

 

图 统计入度为0的点

class Solution {

public:

    vector<int> findSmallestSetOfVertices(int n, vector<vector<int>>& edges) 

    {

        vector<int> in(n,0);

        vector<bool> check(n,false);

        vector<int> ret;

        

        for(auto e:edges)

        {

            int u=e[0];

            int v=e[1];

            in[v]++;

        }

        for(auto e:edges)

            {

                int u=e[0];

                if(in[u]==0 && !check[u])

                {

                    check[u]=true;

                    ret.push_back(u);

                }

            }

            return ret;

    }

};

 

并查集   边和点的关系

找完全连通分量图

edge=n*(n-1)/2

class Solution {
public:
    int countCompleteComponents(int n, vector<vector<int>>& edges) {
        int ans = 0;
        vector<set<int>> m(n + 1, set<int>());

// 构建并查集
        for (int i = 0; i < n; i++) {
            m[i].insert(i);
        }
        for (auto x : edges) {
            m[x[0]].insert(x[1]);
            m[x[1]].insert(x[0]);
        }


        map<set<int>, int> s;
        for (int i = 0; i < n; i++) {
            s[m[i]] ++;   //相同联通量的集合数
        }
        for (auto &[x,y] : s) {
            if (y == x.size()) {

//集合数==联通点数  完全联通图
                ans ++;

            }
        }
        return ans;
    }
};

 

 

模拟题

class Solution {
public:
    int minFlips(vector<vector<int>>& grid) {
        int n = grid.size(), m = grid[0].size();
        int cnt1 = 0, cnt2 = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0, k = m - 1; j < k; j++, k--) {
                if (grid[i][j] != grid[i][k]) cnt1++;
            }
        }
        for (int i = 0; i < m; i++) {
            for (int j = 0, k = n - 1; j < k; j++, k--) {
                if (grid[j][i] != grid[k][i]) cnt2++;
            }
        }
        return min(cnt1, cnt2);
    }
};
 

 

三路快排

class Solution {

public:

    void sortColors(vector<int>& nums) 

    {

        //三指针

        int left=-1,i=0;

        int n=nums.size(),right=n;

 

        while(i<right)

        {

            if(nums[i]==0)

                swap(nums[++left],nums[i++]);

            else if(nums[i]==1)

                i++;

            else if(nums[i]==2)

                swap(nums[--right],nums[i]);

        }

    }

};

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词