LIS

N久没有更新博客了,主要是因为科研任务繁重= =,自己又很菜B,所以没有时间锻炼作为码农的基本素养:Coding。

周末抽空来随机找一个题目练练手。就看到了曾经处理过的动规的经典LIS。以前不理解,现在已经能够理解了。但是要说精髓部分,还是需要经过各种花式训练,

估计才能理解的更加深刻 。

题目连接:

https://leetcode.com/problems/longest-increasing-subsequence/


确保每个序列的美中可能都包含考虑了。



那么每个状态d(n)的含义就是。以num[n]结尾的最长LIS。
那么就考虑当前拿到的数与num[n]能否构成新的LIS,即考虑能否+1.


所有对于d[5], 6 前面有三个比它小的,8比它大,直接构不成,就不考虑。对于所谓考虑漏过8构成LIS的,直接在前面的d[x]中考虑了。
构不成还是要考虑的, 就是不加上1的考虑。
还是要不考虑比当前数字大的LIS,因为考虑了就没有办法形成连贯性的加法。
以上两句话,是我纠结的过程。= =

d[5] = max{d[1], d[2], d[3] } + 1.


对于d[6] = max{d[1],d[2], d[3], d[5]} + 1


好的,那么问题就简单了。

class Solution(object):
    def lengthOfLIS(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums) == 0:
        	return 0;
        if len(nums) == 1:
        	return 1
        d = [1 for i in range(len(nums))]
        for i in range(1,len(nums)):
        	dmax = -1
        	for j in range(0,i):# find satisfy the less condition and d[] array bigger.
        		if nums[j] < nums[i] and d[j] > dmax:
        			dmax = d[j]
        	# if there is some number less than current number
        	if dmax + 1> d[i]:
        		d[i] = dmax + 1
        finalMax = -1
        for each in d:
        	if each > finalMax:
        		finalMax = each
        return finalMax

so = Solution()
print so.lengthOfLIS([1,3,6,7,9,4,10,5,6])

       








代码一出来。
还是有几个编码过程中的错误:
1. 对动态规划中,递归数据理解的不准确。对于迭代推导的d[]数组中的值而言,它就表达的是以对应索引位置的数字结尾的、且该数字必须作为LIS序列一部分的、最长的LIS。 不能说可以绕过前面的数据而构成,比如 1,2,8,9,5.
作为5而言,这个位置的d[]数组,就是3 (1,2,5)。而不是说不使用当前数字5构成的4 (1,2,8,9,)。


2. 对最终返回的最长LIS选择错误。误以为d[]数组中最后一个是最大的,其实不是。基于上述对于d[]数组的理解,相信不难推导出从中选择最大的。


总结:动规这个东西,以前总是不理解,现在好在能够理解一些了。它的思想还是大化小。要理解内涵,觉得就是要理解每个状态所表达的意思。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值