问题描述一个数的序列ai,当a 1 < a 2 < ... < a S 的时候,
我们称这个序列是上升的。对于给定的一个序列(a 1 , a 2 , ..., a N ),
我们可以得到一些上升的子序列(a i1 , a i2 , ..., a iK ),
这里1 <= i1 < i2 < ... < iK<= N。比如,对于序列(1, 7, 3, 5, 9, 4, 8),
有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。这些子序列中
最长的长度是4,比如子序列(1, 3, 5, 8).
你的任务,就是对于给定的序列,求出最长上升子序列的长度(LIS)。
输入数据:输入的第一行是序列的长度N (1 <= N <= 1000)。第二行给
出序列中的N个整数,这些整数的取值范围都在0到10000。
输出要求:最长上升子序列的长度。
输入样例
7
1 7 3 5 9 4 8
输出样例
4
解题思路:假设对n个数求最长子序列,利用动态规划的思想,可以转化为
求若干个子问题的过程,比如先求n-1的最子长序列,n-2,直到第1位数值。
理由是这样,n-1的最长子序列长度已经求得了,那么如果n比n-1大,那么
利用n加入这个子序列,所以长度+1,如果小,那么其子序列的长度就需要
找比n小的最大的子序列长度+1,一定要理解好这句话,因为比前面比n小
的有可能有多个数,但是要找到最大的那个,然后在其基础上+1,就能求出
n的最长子序列的长度。
Python算法实现:
1 from random import randint 2 3 # 生成指定长度的范围为[0, 1000]的整数列表 4 5 6 def generate_integer_list(length): 7 lst = [] 8 for i in range(length): 9 lst.append(randint(0, 1000)) 10 return lst 11 12 13 tempList = generate_integer_list(10) 14 # tempList = [206, 184, 197, 451, 912, 517, 321, 803, 446, 294] 15 # maxLength列表存储每个位置的最长子序列的长度,假设初始是1 16 maxLen = [1]*10 17 18 # 每次求以第i个数为终点的最长上升子序列的长度 19 for i in range(1,10): 20 for j in range(0,i): 21 # 察看以第j个数为终点的最长上升子序列 22 if tempList[i] > tempList[j]: 23 maxLen[i] = max(maxLen[i],maxLen[j]+1) 24 25 maxValue = max(maxLen) 26 indexPos = maxValue 27 outList = [] 28 start = len(maxLen)-1 29 while indexPos > 0: 30 for k in range(start, -1, -1): 31 if maxLen[k] == indexPos: 32 outList.append(tempList[k]) 33 # 往每次从找到匹配最大值的元素的前面查找,不能每次都从后往前找 34 start = k 35 break 36 indexPos -= 1 37 print("原列表为:",end="") 38 print(tempList) 39 print("最长子序列为:%d" % maxValue) 40 print("其中一个最长子序列为:",end="") 41 outList.reverse() 42 print(outList) 43 44 45 """ 46 # 利用bisect进行二分查找 47 from bisect import bisect 48 def longest_inc_sub(seq): 49 end = [] 50 for su in seq: 51 # 查找su在end列表中的位置 52 idx = bisect(end, su) 53 if idx == len(end): 54 end.append(su) 55 else: 56 end[idx] = su 57 return len(end) 58 nums = [10, 6, 19, 23, 31, 20, 8] 59 print(longest_inc_sub(nums)) 60 """ 61 62 """ 63 def lis(arr): 64 n = len(arr) 65 m = [0] * n 66 for x in range(n - 2, -1, -1): 67 for y in range(n - 1, x, -1): 68 if arr[x] < arr[y] and m[x] <= m[y]: 69 m[x] += 1 70 max_value = max(m) 71 result = [] 72 for i in range(n): 73 if m[i] == max_value: 74 result.append(arr[i]) 75 max_value -= 1 76 return result 77 78 arr = [10, 22, 9, 33, 21, 50, 41, 60, 80] 79 print(lis(arr)) 80 """