在算法面试和编程竞赛中,最长递增子序列(Longest Increasing Subsequence,简称LIS)是一个非常经典的问题。它不仅考察你对动态规划(Dynamic Programming, DP)的理解,还广泛应用于数据压缩、生物信息学等领域。
本教程将用通俗易懂的方式,手把手教你如何使用Java语言实现最长递增子序列的动态规划解法,即使你是编程小白,也能轻松掌握!
给定一个整数数组,比如:[10, 9, 2, 5, 3, 7, 101, 18],我们要找出其中最长的严格递增子序列的长度。
注意:子序列不要求连续,但必须保持原有顺序。例如上面的例子中,一个可能的递增子序列是 [2, 3, 7, 18],它的长度是4。而最长的递增子序列长度就是4。
动态规划的核心思想是:把大问题拆成小问题,利用小问题的解构建大问题的解。
对于LIS问题,我们可以定义一个DP数组:
dp[i] 表示以 nums[i] 结尾的最长递增子序列的长度。那么,如何计算 dp[i] 呢?
我们遍历 j = 0 到 i-1,如果 nums[j] < nums[i],说明可以把 nums[i] 接在以 nums[j] 结尾的子序列后面,从而形成一个更长的递增子序列。因此:
dp[i] = Math.max(dp[i], dp[j] + 1);
下面是完整的Java实现代码,包含详细注释:
public class LongestIncreasingSubsequence { public static int lengthOfLIS(int[] nums) { if (nums == null || nums.length == 0) { return 0; } int n = nums.length; // dp[i] 表示以 nums[i] 结尾的最长递增子序列长度 int[] dp = new int[n]; // 初始化:每个元素自身构成长度为1的子序列 for (int i = 0; i < n; i++) { dp[i] = 1; } // 动态规划填表 for (int i = 1; i < n; i++) { for (int j = 0; j < i; j++) { if (nums[j] < nums[i]) { dp[i] = Math.max(dp[i], dp[j] + 1); } } } // 找出dp数组中的最大值,即为答案 int maxLength = 1; for (int len : dp) { if (len > maxLength) { maxLength = len; } } return maxLength; } // 测试方法 public static void main(String[] args) { int[] nums = {10, 9, 2, 5, 3, 7, 101, 18}; System.out.println("最长递增子序列长度为: " + lengthOfLIS(nums)); // 输出:4 }} 注:还有一种基于二分查找的O(n log n)解法,但本教程聚焦于DP基础,适合初学者理解核心思想。
< 而不是 <=。通过本教程,你已经掌握了使用Java最长递增子序列的动态规划解法。这是学习动态规划教程中的经典案例,也是提升Java DP算法能力的重要一步。多加练习,你就能熟练应用这种“状态定义 + 状态转移”的DP思维模式。
记住:理解问题本质比死记代码更重要。动手写一写、改一改,才能真正掌握最长递增子序列实现的精髓!
本文由主机测评网于2025-12-10发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025125855.html