美团点评 2017春招编程题

编程题有题号,应该是随机抽取的。

题目大意

给定一个数列,求它的最长上升子序列的长度。

思路 - DP

很简单的 DP ,先做的编程题,就先赶快写了个 O(n2) 的解法便去做前面的题了。设 dp[i]i 个数为结尾的最长上升子序列的长度,状态转移方程为: dp[i]=max(dp[j])+1,j<i&&num[j]<num[i]

全部做完后,发现还有半个小时,就开始想 O(nlogn) 的解法,虽然已经忘了具体怎么写,但是记得在处理的过程中,以上升子序列的长度为下标,上升子序列的最后一个数为值(长度相同,取较小值),就能构造出一个单调递增的数组,然后就能用二分找到最后一个数小于当前数的最长上升子序列的长度。

熟练后就不需要 dp 数组了

代码

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int n, num, l, r, mid, mx;
int mn[100003];//mn[i]表示长度为i的上升子序列中,最后一个数的最小值

int main() {
    while(1 == scanf("%d", &n)) {
        mx = 0;
        memset(mn, 0x3f, sizeof(mn));
        while(n-- > 0) {
            scanf("%d", &num);
            l = 1;
            r = mx;
            while(l <= r) {
                mid = (l + r) >> 1;
                if(mn[mid] < num) {
                    l = mid + 1;
                }
                else {
                    r = mid - 1;
                }
            }
            mn[r + 1] = min(mn[r + 1], num);
            mx = max(mx, r + 1);
        }
        printf("%d\n", mx);
    }
    return 0;
}

美团点评还有道读程序题,给了一个Activity的创建和销毁的函数,创建函数中有文件读取,但是没有关闭输入流。只发现了这一个错误。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值