zoukankan      html  css  js  c++  java
  • 128. Longest Consecutive Sequence

    问题描述:

    Given an unsorted array of integers, find the length of the longest consecutive elements sequence.

    Your algorithm should run in O(n) complexity.

    Example:

    Input: [100, 4, 200, 1, 3, 2]
    Output: 4
    Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.

    解题思路:

    讲真这题一开始我没什么思路,然后看到tag里有并查集,我就往并查集的方向想了。

    nums中数字n,若n-1出现在nums中,对n 和 n-1执行union操作。

    Find方法中用到了路径压缩

    最后对每个数字的父节点计算它的子节点的个数,这就是最长的连续数字

    这里有一个坑就是数组中的数字可能会出现重复,若直接用数字来标识,那么会出现错误:

    如:[0,0,-1]

    若对数组中每一个数字进行find并对根节点+1的话,那么最后会得到3。

    这里可以用下标来进行标识。

    以上只是复习一下并查集。

    因为我的并查集只打败了6% ಠ_ಠ

    更快的方法:

    使用集合存储数组中的数字。

    对数组中的每一个数字,首先检查它是否还存在在集合中,若存在,将计数变量cnt设为0并从集合中删除该数字。

    此时检查比它小1的数字是否存在,若存在删除它同时计数自增1一,再检查更小的。

    对比它大1的数字同理。

    当遇到这类问题时,我们不一定要考虑如何遍历数组,也可以考虑将其放到一个新的数据结构中。

    代码:

    Union Find:

    class Solution {
    public:
        int longestConsecutive(vector<int>& nums) {
            unordered_map<int,int> parents;
            unordered_map<int,int> rec;
            for(int i = 0; i < nums.size(); i++){
                parents[i] = i;
                rec[nums[i]] = i;
            }
            for(auto p : rec){
                if(rec.count(p.first-1)){
                    Union(parents, rec[p.first-1] , rec[p.first]);
            }
        }
            return findMax(parents, nums);   
        }
    private:
        int find(unordered_map<int,int> &parents, int a){
            if(parents[a] == a)
                return a;
            return parents[a] = find(parents, parents[a]);
        }
        
        void Union(unordered_map<int,int> &parents, int a, int b){
            int rootA = find(parents, a);
            int rootB = find(parents, b);
            if(rootA != rootB)
                parents[rootB] = rootA;
        }
        
        int findMax(unordered_map<int, int> &parents, vector<int> &nums){
            int ret = 0;
            unordered_map<int,int> cnt;
            for(int i = 0; i < nums.size(); i++){
                ret = max(ret, ++cnt[find(parents, i)]);
            }
            return ret;
        }
    };

    使用集合:

    class Solution {
    public:
        int longestConsecutive(vector<int>& nums) {
            unordered_set<int> s(nums.begin(), nums.end());
            int ret = 0;
            for(int i = 0; i < nums.size(); i++){
                if(s.count(nums[i])){
                    int cnt = 1;
                    int prev = nums[i]-1;
                    int next = nums[i]+1;
                    s.erase(nums[i]);
                    while(s.count(prev)){
                        s.erase(prev);
                        prev--;
                        cnt++;
                    }
                    while(s.count(next)){
                        s.erase(next);
                        next++;
                        cnt++;
                    }
                    ret = max(ret, cnt);
                }
            }
            return ret;
            
        }
    };
  • 相关阅读:
    mybatis使用Example进行条件查询
    博客园页面DIY
    内网穿透
    使用ResponseEntity进行返回json数据
    spring中的ResponseEntity理解
    springboot整合mybatis通用Mapper
    解决pip安装过慢的问题
    【记录】linux 命令拷贝文件到远程服务器,linux下载文件到本地
    【记录】ELK之logstash同步mysql数据到Elasticsearch ,配置文件详解
    【记录】logstash 命令解释
  • 原文地址:https://www.cnblogs.com/yaoyudadudu/p/9191951.html
Copyright © 2011-2022 走看看