• 从零学算法128


    128.给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
    请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
    示例 1:
    输入:nums = [100,4,200,1,3,2]
    输出:4
    解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
    示例 2:
    输入:nums = [0,3,7,2,5,8,4,6,0,1]
    输出:9

    • 这里就直接调 api 排序了,排序后最长连续序列在数组中就一定为连续的整数了。设 dp[i] 为以 nums[i] 结尾的子数组的最长序列,dp[i] 有两种情况,当 nums[i]=nums[i-1]+1 表示它能和前一个数组成连续的序列,就为 dp[i-1]+1,否则就没法连续, dp[i]=1。初始情况也很好理解,dp[0]=1 表示长度为 1 的数组无论如何存在连续序列长度为 1。
    • 时间复杂度: O ( n ) O(n) O(n)
    • 空间复杂度: O ( n ) O(n) O(n)
    •   public int longestConsecutive(int[] nums) {
            int n = nums.length;
            if(n == 0)return 0;
            Arrays.sort(nums);
            // 由于 dp 更新时只和前一个结果有关,所以不需要数组
            int dp = 1;
            int ans = dp;
            List<Integer> list = new ArrayList<>();
            // 去重,你也可以用一个变量记录前一个数
            // 这样也就不需要 list 了,空间复杂度将为 O(1)
            for(int i=0;i<n;i++){
                while(i<n-1 && nums[i]==nums[i+1])i++;
                list.add(nums[i]);
            }
            for(int i=1;i<list.size();i++){
                if(list.get(i)==list.get(i-1)+1)dp++;
                else dp=1;
                ans=Math.max(ans,dp);
            }
            return ans;
        }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
    • 去重优化
    •   public int longestConsecutive(int[] nums) {
            int n = nums.length;
            if(n == 0)return 0;
            Arrays.sort(nums);
            int dp = 0;
            int ans = 0;
            int pre=nums[n-1]+1;
            for(int i=0;i<n;i++){
                while(i<n-1 && nums[i]==nums[i+1])i++;
                if(nums[i]==pre+1)dp++;
                else dp=1;
                pre=nums[i];
                ans=Math.max(ans,dp);
            }
            return ans;
        }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    • 还有用 set + 递归暴力解的:限定某个起点,从 set 中找连续的序列长度很容易,这里的计算用递归表示了。
    •   Set<Integer> set = new HashSet();
        public int longestConsecutive(int[] nums) {
            int n = nums.length;
            int ans = 0;
            if(n == 0)return ans;
            // set 去重
            Arrays.stream(nums).forEach(v->{set.add(v);});
            for(int x:set){
            	// 如果有 x-1 那从 x-1 开始的长度肯定更长,所以跳过 x
                if(set.contains(x-1))continue;
                // 这就等于比较每个连续序列的长度
                ans = Math.max(ans,dfs(x,0));
            }
            return ans;
        }
        // 计算从 x 开始的最长序列长度
        int dfs(int x,int res){
            if(set.contains(x))return dfs(x+1,res+1);
            else return res;
        }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
  • 相关阅读:
    何时使用Elasticsearch而不是MySql
    基于RK3588的全国产鸿蒙边缘计算工控机在智能交通ETC收费系统的应用
    打造千万级流量秒杀系统第二课 功能需求:秒杀活动信息是如何管理的?
    Scala词频统计
    PTA编程的一些总结
    Wework创始人再创业,靠美版“自如”估值10亿美金
    下南洋捕风
    Python爬虫进阶:提升爬虫效率
    SpringBoot整合定时任务遇到的多实例问题
    SQL Server批量删除数据库中的表
  • 原文地址:https://blog.csdn.net/m0_53256503/article/details/136471955