美团23届实习(3月5号)笔试题解

题目1

1.1、题目分析

        其实本题和最长递增子序列的求解一模一样。可以利用动态规划来快速实现。

        为了能够找到可重集中 最大的不连续子集的大小,我们先对原始数据升序,然后dp:

1)dp[i]含义:

        表示i之前包括i的最长上升子序列的长度。即下标i对应元素包含在内的不连续子集最大长度;

2)递推公式:

        dp[i] = Max(dp[i],dp[j]+1),

        在满足条件下(nums[i]>nums[j]+1),位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 + 1 的最大值。注意这里不是要dp[i] 与 dp[j] + 1进行比较,而是我们要取dp[j] + 1的最大值

3)初始化

        每一个i,对应的dp[i](即最长上升子序列)起始大小至少都是1.

4)遍历顺序:

        dp[i] 是有0到i-1各个位置的最长升序子序列 推导而来,那么遍历i一定是从前向后遍历。

        j其实就是0到i-1,遍历i的循环在外层,遍历j则在内层,代码如下:

for (int i = 1; i < nums.size(); i++) {
    for (int j = 0; j < i; j++) {
        if (nums[i] > nums[j]+1) dp[i] = max(dp[i], dp[j] + 1);
    }
    if (dp[i] > result) result = dp[i]; // 取长的子序列
}

1.2、代码

import java.io.*;
import java.util.*;
class test  
{
	public static void main (String[] args) throws java.lang.Exception
	{
	    //输入
	    Scanner sc =new Scanner(System.in);
	    int n = sc.nextInt();
	    int[] arr = new int[n];
	    for(int i=0;i<n;i++){
	        arr[i] = sc.nextInt();
	    }
	    Arrays.sort(arr);
	 
	    //算法
	    /*
	    dp[i]  表示从0~i范围内的最大不连续子集长度
	    dp[i]=dp[j]+1  表示dp[i]的长度 等前面0到j的各个位置满足条件+1  从中选出最长的作为dp[i]的长度
	    **/
	    int [] dp = new int[arr.length];
	    Arrays.fill(dp,1);//初始化 每一个元素可以看做是长度为1不连续子集长度
	    int result =0;
	    for(int i=1;i<dp.length;i++){
	        for(int j=0;j<i;j++){
	            
	            if(arr[i]-arr[j]>1){
	                dp[i]=Math.max(dp[i],dp[j]+1);
	            }
	            if(dp[i]>result) result=dp[i];// 维护当前最长的不连续长度
	            
	        }
	    }
	    
	    
		System.out.println(result);
	}
}

-=======================================

题目二

1、题目描述

未完  待续~~~~

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值