LeetCode-128:Longest Consecutive Sequence

题目

  • 给出一个未排序的数组,找出最长的连续序列,连续指的是像……11、12、13、14……这样的,要求算法时间复杂度为O(n)。
  • 做一些说明:不知道会不会有重复的数字,如果有应该怎么算?看最后AC的情况,应该是如果有重复的数字,不算在序列里边。

思路

1、自己的思路

  • 我刚开始是想用hash结构来处理,不过又觉得hash好像时间复杂度也挺高,不知道谁给我的hash时间复杂度搞得感觉,是上上hash查找时间复杂度就是O(1),这里就是用hash结构。
  • 说一下为什么使用hash,如果你要查找的值是确切的,你知道的,就可以用hash,立马查找出来,那再说一下不能用hash的地方,比如排序,你只知道下一个数字比当前小还是大,并不确切知道是谁,这样就没法用hash了,所以注意hash结构的使用要是很关键的。
  • 第一步当然是将给定数组的元素保存在Set集合中(Java的Set集合,底层使用hash)。
  • 然后开始遍历整个数组,在数组中取出一个数字num,然后向左查找(递减查找),看看在Set集合中是否包含num-1,包含的话继续判断是否有num-2,一次类推,向左找完,接着向右找(递增查找),num+1、num+2等等。
  • 在上一步查找的时候需要做两件事情:第一是记录向左向右查找的个数,这将是这个序列的长度。第二是,凡是遍历过的数字,都从Set集合中移除。这样做的好处很明显,比如存在一个序列2、3、4,便利到2的时候,其实已经找到了这个序列,遍历3和4的时候就没有必要再找了。还有个极端的例子,M个数字,刚好是从1~M的整数,如果不将遍历过的数字从Set集合中移除,那么时间复杂度将是O(n^2)。
  • 由于有从Set集合中删除元素的操作,所以遍历数组的第一步应该是先判断Set集合中还有没有该元素,没有的话说明已经处理过,continue就行。
  • 最后得出了最长的序列长度max。
  • 这里其实除了使用hash结构,几乎没什么考点,就是解决问题的一些小技巧而已。

2、leetcode上一些更有意思的想法

  • 有人用一个空的map,在循环里边里边进行记录,end、start为key,length为value,还是很有意思的。
  • 有一个非常有意思的,代码短小,一句话概括就是:便宜遇到一个数字n,如果这个数字是序列的开始(n-1不在set中那么就是开始),那就查找n+1、n+2等等在不在set中,最后记录长度。乍看以为时间复杂度应不符合,细细一想,其实是符合的,代码在这里,可以自己去看 Simple O(n) with Explanation - Just walk each streak

时间复杂度

  • 主要看一下几个for循环,外边毫无疑问是O(n),那么里边嵌套的两个呢?其实细细一想,这两个循环体执行的总次数应该是n,因为每个元素只能被遍历一遍,又因为这个大循环体能被执行n次,那平均时间复杂度应该是n/n,是O(1),此时加上外边的大循环,时间复杂度也就是O(n)。
  • 好了真的很迷糊,其实一眼就能看出来是O(n)。

代码

Java代码,基于自己的思路

public class Topic128 {

    public static int longestConsecutive(int[] nums) {
        if(nums == null || nums.length == 0)
            return 0;
        
        Set<Integer> set = new HashSet<>();
        for(int i = 0; i < nums.length; i++)
            set.add(nums[i]);
        
        int max = 0;
        int len = 0;
        for(int i = 0; i < nums.length; i++) {
            int num = nums[i];
            if(!set.contains(num))
                continue;
            len = 1;
            set.remove(num);
            for(int tmp = num-1; set.contains(tmp); tmp--, len++)
                set.remove(tmp);
            for(int tmp = num+1; set.contains(tmp); tmp++, len++)
                set.remove(tmp);
            
            max = len > max ? len : max;
        }
        return max;
    }
}

猜你喜欢

转载自blog.csdn.net/DragonFreedom/article/details/81907209