leetcode 128. Longest Consecutive Sequence

33 篇文章 0 订阅
3 篇文章 0 订阅

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: union find, array

method 1 sort

直接排序求解

method 2 set

利用set的特性,不断地remove

使用一个set,对每一个数,检查是否有它的前继和后继,如果有则推进,感觉相当于滑动窗口的变种,使用remove方法可以减少遍历的数据量
使用sort,实际上速度更快

public int longestConsecutive(int[] nums) {
        int res = 0;
        HashSet<Integer> set = new HashSet<>();
        for (int i = 0; i < nums.length; i++) {
            set.add(nums[i]);
        }

        for (int num:nums) {
            if (set.remove(num)){
                int prev = num-1;
                int next = num+1;
                while (set.remove(prev)) prev--;
                while (set.remove(next)) next++;

                res = Math.max(res, next-prev-1);
            }
        }

        return res;
    }

method 3 union find

https://www.cnblogs.com/yelir/p/11549392.html 并查集的介绍

  1. 使用并查集时par数组的值都是父结点的索引,所以不需要特殊考虑,需要考虑的是如何将原数组中的值和par数组中的索引对应起来,本题使用map
  2. 本题提供了如何求每个树的节点个数,使用一个额外的size数组,每次union的时候加起来即可
  3. par数组、find方法和union方法是模板代码,要牢记
vector<int> par;
	vector<int> size;
    
    int find_(int x){
		if (par[x] == x) return x;
		par[x] = find_(par[x]);
		return par[x];
	}

	void union_(int x, int y){
		int root1 = find_(x);
		int root2 = find_(y);
		if (root1 != root2){
			par[root1] = root2;
			size[root2] += size[root1];
		}
		
	}

	int longestConsecutive(vector<int>& nums) {
		if (nums.size() == 0) return 0;
		unordered_map<int, int> map;

		par.resize(nums.size(), -1);
		size.resize(nums.size(), 1);

		for (int i = 0; i < nums.size(); i++){
			int num = nums[i];
			par[i] = i;
			map[num] = i;
		}

		for (int i = 0; i < nums.size(); i++){
			int num = nums[i];
			int index = map[num];
			if (map.count(num - 1)) union_(map[num - 1], index);
			if (map.count(num + 1)) union_(index, map[num + 1]);
		}

		int longest = 1;
		for (int i : size)		longest = max(i, longest);
		
		return longest;
	}

summary:

  1. set等效代替滑动窗口
  2. 并查集重点(本题并查集模板代码要牢记)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值