LeetCode刷题——最长递增子序列#300#Medium

最长递增子序列题目的思路探讨与源码
    最长递增子序列的题目如下图,该题属于动态规划和二分查找类型的题目,主要考察对于动态规划和二分查找法的使用和理解。本文的题目作者想到2种方法,分别是动态规划方法和二分查找法,其中动态规划方法使用java进行编写,而二分查找法使用Python进行编写,当然这可能不是最优的解法,还希望各位大佬给出更快的算法。
在这里插入图片描述
    本人认为该题目可以使用动态规划方法,首先计算数组的长度,并且判断是否为空,如果长度是0就直接返回0并且结束程序。然后开始进行动态规划的数组初始化,遍历原始数组nums,第一个下标是从0到数组下标的,第二个下标是从0到第一个下标的,动态规划内部的核心思路是,当前的动态数组的值是取决于max{dp[i],dp[j]+1}更大值,当每次内部循环结束的时候,都要把最终的最长递增子序列长度进行更新。那么按照这个思路我们的Java代码如下:

#喷火龙与水箭龟
class Solution {
    public int lengthOfLIS(int[] nums) {
        int lenNum=nums.length;
		if(lenNum==0){
			return 0;
		}
		int finalNum=0;
        int[] dynamicArray = new int[lenNum];
        Arrays.fill(dynamicArray,1);
        for(int jr=0;jr<nums.length;jr++){
            for(int kv=0;kv<jr;kv++){
                if(nums[kv]<nums[jr]){
				    dynamicArray[jr]=Math.max(dynamicArray[kv]+1,dynamicArray[jr]);
				} 
            }
            finalNum=Math.max(dynamicArray[jr],finalNum);
        }
        return finalNum;
    }
}

在这里插入图片描述
    显然,我们还可以使用二分查找的方法进行处理,首先进行长度计算和初始化赋值,将一个历史数组全部初始化为0的元素,然后开始遍历,每次计算下标的中间值,如果历史数组的值比当前元素值小,则左边的下标更新为中间值下标加1,否则右边的下标更新为中间值,并且在循环的末尾对右侧的下标进行判断,如果和最终的返回值一样则会将最终的返回值加1,最后返回结果即可。所以根据这个思路就可以写出代码,下面是Python代码部分:

#喷火龙与水箭龟
class Solution:
    def lengthOfLIS(self, nums: [int]) -> int:
        lenNum=len(nums)
        endNum=lenNum*[0]
        finalNum=0
        for np in nums:
            iv=0
            jv=finalNum
            while(iv<jv):
                midNum=(iv+jv)//2
                if(endNum[midNum]<np):
                    iv=midNum+1
                else:
                    jv=midNum
            endNum[iv]=np
            if(jv==finalNum):
                finalNum=finalNum+1
        return finalNum

在这里插入图片描述
    从结果来说java版本的动态规划法的速度比较一般,但是python版本的二分查找方法的速度还不错,但应该是有更多的方法可以进一步提速的,希望朋友们能够多多指教,非常感谢。

猜你喜欢

转载自blog.csdn.net/qq_26727101/article/details/119696327