完美世界招聘笔试(子序列)

题目描述:
给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱)
例如:给定一个长度为8的数组A{1,3,5,2,4,6,7,8},
则其最长的单调递增子序列为{1,2,4,6,7,8},长度为6。

输入描述:

第一行包含一个整数T,代表测试数据组数。
对于每组测试数据: N-数组的长度
a1 a2 … an (需要计算的数组)
保证: 1<=N<=3000,0<=ai<=MAX_INT.
输出描述:
对于每组数据,输出一个整数,代表最长递增子序列的长度。
输入例子:
2
7
89 256 78 1 46 78 8
5
6 4 8 2 17
输出例子:
3
3
分析:这道题说实话也困扰了我两天,今天晚上才想明白的,具体实现其实很简单,就是循环内嵌循环这个比较的意思在里面。很多人说到了动态规划,很抱歉,鄙人能力有限,对于动态规划来说,我觉得是设置个临时变量来决定继续不继续某几句程序而已。对于这道题我分两部分来说下:
第一部分,就是所谓的对一个无序序列来求它的最长递增子序列。具体实现是通过三层循环依次遍历,得到最终想要的结果,解析和实现代码如下:
#-*-coding:UTF-8-*-
def CalMaxLen(Objlist):
    b = []#b是用来存放每一次遍历或者说选择好的递增序列的长度的
    for i in range(len(Objlist)):
        #print 'when i =%d:' % i
        #max = Objlist[i]
        for j in range(i+1,len(Objlist)):
            print 'when i= %d,from %dth ele:' % (i,j)
            #当第i次循环,也就是说下标为i的元素作为我们要找的
            #递增序列的第一个,这个时候呢,我们就开始从i后面的
            #元素开始遍历了,
            k = j
            #请注意k是什么呢?就是一个标记器,当第i次循环
            #也就是说下标为i的元素为递增序列第一个元素时
            #我们依次要选择从i+1、i+2、i+3…i+len(objlist)开始
            #因为递增序列中的元素在原序列中可以不连续,但必须满足
            #递增。
            a = []
            #a用来存放每一次最基本的循环后的递增序列
            #比如i=0,j=1时我们找到的递增序列
            max = Objlist[i]
            #我们每次把开始元素设置成最大,这样进行选择
            a.append(Objlist[i])#先把起始元素加进递增表里
            for m in range(k,len(Objlist)):
                if Objlist[m] >= max:
                    max = Objlist[m]
                    a.append(Objlist[m])
                    #如果从下标为j的元素后算起。大于max的就更新max
                else:
                    continue
                    # 小于的话那就继续找,continue
            print 'the addly list is', a
            #输出此次循环后得到的递增序列
            b.append(len(a))
            #然后把这个递增序列的长度放到最终各个循环次数下的
            # 递增序列长度表中
        if i == len(Objlist)-1:
            a = []
            a.append(Objlist[i])
            print 'when i is the last ele:'
            print 'the addly list is only:',a
            #这里要注意,当i等于最后一个元素的下标时
            #上面的j就取不到了,这个时候那我们就打印最后一个元素
            #因为它必然就是一个单元素
    c = b[0]
    for i in range(len(b)):
        if c <= b[i]:
            c = b[i]
    return c
s = map(int,raw_input().split())
d = CalMaxLen(s)
print 'So, the Max length of the addly list in the objective list is: ',d

E:\Python27\python.exe D:/python/python算法/b.py
1 5 2 4
when i= 0,from 1th ele:
the addly list is [1, 5]
when i= 0,from 2th ele:
the addly list is [1, 2, 4]
when i= 0,from 3th ele:
the addly list is [1, 4]
when i= 1,from 2th ele:
the addly list is [5]
when i= 1,from 3th ele:
the addly list is [5]
when i= 2,from 3th ele:
the addly list is [2, 4]
when i is the last ele:
the addly list is only: [4]
So, the Max length of the addly list in the objective list is:  3

Process finished with exit code 0
上面就是这个问题最核心处理过程的解决方法
接下来第二部分,就是针对这道题目的输入来做个输出了,当然我会把不必要的输出给注释掉:
#-*-coding:UTF-8-*-
def CalMaxLen(Objlist):
    b = []#b是用来存放每一次遍历或者说选择好的递增序列的长度的
    for i in range(len(Objlist)):
        #print 'when i =%d:' % i
        #max = Objlist[i]
        for j in range(i+1,len(Objlist)):
            #print 'when i= %d,from %dth ele:' % (i,j)
            #当第i次循环,也就是说下标为i的元素作为我们要找的
            #递增序列的第一个,这个时候呢,我们就开始从i后面的
            #元素开始遍历了,
            k = j
            #请注意k是什么呢?就是一个标记器,当第i次循环
            #也就是说下标为i的元素为递增序列第一个元素时
            #我们依次要选择从i+1、i+2、i+3…i+len(objlist)开始
            #因为递增序列中的元素在原序列中可以不连续,但必须满足
            #递增。
            a = []
            #a用来存放每一次最基本的循环后的递增序列
            #比如i=0,j=1时我们找到的递增序列
            max = Objlist[i]
            #我们每次把开始元素设置成最大,这样进行选择
            a.append(Objlist[i])#先把起始元素加进递增表里
            for m in range(k,len(Objlist)):
                if Objlist[m] >= max:
                    max = Objlist[m]
                    a.append(Objlist[m])
                    #如果从下标为j的元素后算起。大于max的就更新max
                else:
                    continue
                    # 小于的话那就继续找,continue
            #print 'the addly list is', a
            #输出此次循环后得到的递增序列
            b.append(len(a))
            #然后把这个递增序列的长度放到最终各个循环次数下的
            # 递增序列长度表中
        if i == len(Objlist)-1:
            a = []
            a.append(Objlist[i])
            #print 'when i is the last ele:'
            #print 'the addly list is only:',a
            #这里要注意,当i等于最后一个元素的下标时
            #上面的j就取不到了,这个时候那我们就打印最后一个元素
            #因为它必然就是一个单元素
    c = b[0]
    for i in range(len(b)):
        if c <= b[i]:
            c = b[i]
    return c
n = int(raw_input())#n是输入的组数
endlist = []
for i in range(n):
    r = int(raw_input())
    s = map(int, raw_input().split())
    endlist.append(CalMaxLen(s))
for i in endlist:
    print i
输出示例:
E:\Python27\python.exe D:/python/python算法/MaxAddlyList.py
2
7
89 256 78 1 46 78 8
5
6 4 8 2 17
3
3

Process finished with exit code 0
OK!收工!
总结一下就是:思路要清晰,至于说这个程序是否还要怎么优化,希望大神来指点!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值