前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >128. 最长连续序列

128. 最长连续序列

作者头像
Krains
发布2020-08-19 15:20:31
3050
发布2020-08-19 15:20:31
举报
文章被收录于专栏:KrainsKrains

# 题目链接

# 贪心算法

最主要的思路是将所有数存入set集合,然后再遍历数组,如果一个数不是当前连续序列的第一个,则不计数,当它是序列中第一个数才统计其所在连续序列的长度。

这样做正确是因为如果一个数不是一个连续序列的开头,那么从它开始往后查找总拿不到最长的连续序列的长度,我们贪心的用一个连续序列的开始元素去计算其长度,能够将时间均摊到O(1)O(1)O(1)。

class Solution {

    public int longestConsecutive(int[] nums) {
        int ans = 0;
        Set<Integer> set = new HashSet<>();
        for(int num : nums){
            set.add(num);
        }
        for(int num : set){
            // 如果set中存在num之前的一个数,说明当前num不是连续序列的开始
            if(set.contains(num-1))
                continue;
            int cur = num;
            // 此时num为一个连续序列的开始,现在才统计其所在连续序列长度
            // 在整个for循环中,此while循环总共走了n次,因为数组中的数只属于一个连续序列
            // 而我们每次只从连续序列的开始往后走
            while(set.contains(cur))
                cur++;
            ans = Math.max(cur-num, ans);
        }
        return ans;
    }
}

# 复杂度分析

  • 时间复杂度:O(n)O(n)O(n)
  • 空间复杂度:O(n)O(n)O(n)

# 哈希表

map中key是连续序列的端点,value存的是该区间的长度,详见代码

class Solution {

    public int longestConsecutive(int[] nums) {
        int ans = 0;
        Map<Integer, Integer> map = new HashMap<>();
        for(int num : nums){
            // 如果num不在任何已存在的区间
            if(!map.containsKey(num)){
                // 当前num不存在于区间,找到以num-1为结尾的连续区间的长度
                int lLen = map.getOrDefault(num-1, 0);
                // 找到以num+1为开始的连续区间的长度
                int rLen = map.getOrDefault(num+1, 0);
                // 加入num之后最新的区间长度
                int curLen = lLen + rLen + 1;
                ans = Math.max(ans, curLen);
                // num为区间[num-lLen, num+rLen]中的值,无论存什么值都无所谓
                // 因为在找区间的时候只会找到num所在的连续序列的左右端点
                map.put(num, -1);
                // 更新左端点开始连续序列的长度
                map.put(num-lLen, curLen);
                // 更新右端点结尾连续序列的长度
                map.put(num+rLen, curLen);
            }
        }
        return ans;
    }
}


# 并查集

  • 哈希表parents中key表示员工,value该员工的上司,若key等于value,则该员工没有上司
  • 哈希表count中key表示某上司手下管理的人数,包括自己
  • 将数组中所有相差为1的数联合union起来
  • 最终某上司管理的最大人数即为答案

# 参考代码

class Solution {
    Map<Integer, Integer> parents = new HashMap<>();
    Map<Integer, Integer> count = new HashMap<>();

    // 带路径压缩的找上司
    public int find(int x){
        int p = parents.get(x);
        if(p == x)
            return p;
        // t为x的最终boss
        int t = find(p);
        // 直接将x的上司设置为t,将路径压缩
        parents.put(x, t);
        return t;
    }

    // 将x与y联合
    public void union(int x, int y){
        int p1 = find(x);
        int p2 = find(y);
        if(p1 == p2)
            return;
        // 若x与y的上司不是同一个人,则设置p2为p1的上司
        parents.put(p1, p2);
        // 此时p2手下的人数就为p1手下管理的人数加p2手下的人数
        count.put(p2, count.get(p1) + count.get(p2));
    }

    public int longestConsecutive(int[] nums) {
        int ans = 0;
        Set<Integer> set = new HashSet<>();
        // set去重,同时初始化parents和count
        for(int num : nums){
            parents.put(num, num);
            count.put(num, 1);
            set.add(num);
        }
        for(int num : set){
            if(set.contains(num-1))
                union(num, num-1);
            if(set.contains(num+1))
                union(num, num+1);
            // 查找num的最终boss的管理人数与当前ans相比,留最大
            ans = Math.max(ans, count.get(find(num)));
        }
        return ans;
    }
}

# 复杂度分析

  • 时间复杂度:O(n)O(n)O(n)
  • 空间复杂度:O(n)O(n)O(n)
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-08-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • # 题目链接
  • # 贪心算法
    • # 复杂度分析
    • # 哈希表
    • # 并查集
      • # 参考代码
        • # 复杂度分析
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档