每日一题算法:2020年6月6日 最常连续序列longestConsecutive

2020年6月6日 最常连续序列longestConsecutive

在这里插入图片描述

默认格式:

class Solution {
   
    public int longestConsecutive(int[] nums) {
   

    }
}

解题思路:

暴力破解:当遇到问题的第一时间,先找到暴力破解该如何写。

先排序,再迭代。

先把数组通过排序算法变成有序的数组,然后在进行迭代的方式来判断最常的连续序列。

那么就要说一说常用的几种排序算法了。这也是面试经常考的内容

1:冒泡排序

主体思路:从头开始把每一个元素和后面的一个元素进行比较,比如A和B比,A比B小,就拿B和C去比,如果A比B大,那么把AB位置互换,然后用A和C去比较。

这样每一次循环会让整个数组更加趋近有序,多次循环之后就能将数组变为有序数组。

2,选择排序

每一次循环找出最小的那一个,把他放在数组前面的位置

3,插入排序

插入排序非常直观,把前n项作为一个有序的数组,然后下一个值在前面的数组中找到自己的位置,变成一个新的有序数组。

排序完成后就可以轻松做到找到最长的连续数组。

代码就不写了,这些个排序算法的复杂度肯定不是O(n)就能解决的,所以这只是为了提供一个思路。

而且明显可以在排序的过程中完成连续性的判断,就比如选择排序每次在选择的时候判断和之前是否是连续的。

思路2:

我们首先要找出这题中的算法和排序算法有什么不一样的地方,因为排序不是必须的,我们只需要获取长度就可以了,所以我们可以对排序算法进行改进,变为我们需要的算法。

关键信息:连续,怎么判断一个序列是否连续呢?

想法:

我新建一个链表节点类型,每一个对象都有一个下一个链表节点对象和一个值,然后我将他放置在一个集合中,判断在这个集合中是否存在和他相邻的节点,如果存在,那么连接起来,如果不存在,那么就先单独放置。

1,前面四个值都是单独的,就直接放置在这里
在这里插入图片描述

2,3的下一个值存在,所以直接把3接在4的下一个

在这里插入图片描述
4,插入2的时候,有上一个1和下一个3,把他们连起来。

在这里插入图片描述
这样就实现了找到最长的连续序列。然后遍历一遍这个集合就完成了找到最长序列的功能

首先是集合的选择,这样看起来是应该选择使用Map类型来作为集合。

如何连接呢?实际上不需要连接,只需要同步长度就可以了,但是我们需要一头一尾两个节点来更新长度,比如插入2的时候,根据3获取到的尾节点是4,头节点是3,2插入后由于2插入在3的头部,所以头结点改为2的头结点1,尾节点改为3的尾节点4,同时刷新头尾节点上记录的长度和头尾节点位置。

在这里插入图片描述
想法不错可是实现的方式不好,使用了多次的跳转导致了耗时增加。虽然时间复杂度是O(n)但是耗时还是非常久的。

public class longestConsecutive {

    class MyLinked{
            MyLinked start=this;
            MyLinked end=this;
            int len=1;
        }
        public int longestConsecutive(int[] nums) {
            HashMap<Integer,MyLinked> map=new HashMap<>();
            for(int i=0;i<nums.length;i++){

                //如果不存在,先创建一个
                if(map.get(nums[i])==null){
                    MyLinked myLinked=new MyLinked();
                    map.put(nums[i],myLinked);
                }else {
                    continue;
                }

                MyLinked myLinked=map.get(nums[i]);

                //寻找下一个整数在集合中是否已经存在
                if(map.get(nums[i]+1)!=null){
                    //与尾部对接
                    myLinked.start.end=map.get(nums[i]+1).end;
                    map.get(nums[i]+1).end.start=myLinked.start;

                    //累计长度
                    myLinked.start.end.len+=myLinked.len;
                    myLinked.start.len=myLinked.start.end.len;
                }

                //寻找上一个整数在集合中是否已经存在
                if(map.get(nums[i]-1)!=null){
                    //与头部对接
                    myLinked.end.start=map.get(nums[i]-1).start;
                    map
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值