
思路:
使用递归来理解题目,然后在看如何优化,假设我当前使用元素那么最长是多少,如果不使用当前元素最长是多少,然后取最大值。
代码如下:
//算出最长递增子序列的长度
    public static int lengthOfLIS02(int[] nums) {
        if (nums==null||nums.length==0){
            return 0;
        }
        if (nums.length==1){
            return 1;
        }
        return process(nums,0,-1,0,nums.length);
    }
    //从index...到N 最长的递增子序列是多长
    public static int process(int[] arr,int index,int preIndex,int curLen,int N){
      if (index==N){
          return curLen;
      }
      //当前index不要
      int p1=process(arr,index+1,preIndex,curLen,N);
      int p2=0;
      //当前index 要
      if (preIndex == -1 || arr[index] > arr[preIndex]){
          p2=process(arr,index+1,index,curLen+1,N);
      }
      return Math.max(p1,p2);
    } 
改成动态规划:其中dp[i]表示以nums[i]结尾的最长子序列是多少
class Solution {
    /**
     * 计算数组 nums 的最长递增子序列的长度。
     * 使用动态规划,时间复杂度 O(n^2)。
     *
     * @param nums 输入的整数数组
     * @return 返回最长递增子序列的长度
     */
    public static int lengthOfLIS(int[] nums) {
        // 如果输入数组为空或长度为0,直接返回0
        if (nums == null || nums.length == 0) {
            return 0;
        }
        // 创建dp数组,dp[i]表示以nums[i]结尾的最长递增子序列的长度
        int[] dp = new int[nums.length];
        // maxLen用于记录并更新全局的最长递增子序列的长度
        int maxLen = 0;
        // 从后向前遍历数组,以保证每次计算dp[i]时,dp[j] (j > i)都已经被计算
        for (int i = nums.length - 1; i >= 0; i--) {
            dp[i] = 1;  // 初始化dp[i]为1,因为最短的子序列至少包含自身
            // 内层循环用于比较nums[i]和其后面的所有元素nums[j]
            for (int j = i + 1; j < nums.length; j++) {
                // 如果nums[j]大于nums[i],则可以将nums[i]添加到以nums[j]结尾的递增子序列中
                if (nums[j] > nums[i]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1); // 更新dp[i]为最大值
                }
            }
            // 更新全局最长递增子序列的长度
            maxLen = Math.max(maxLen, dp[i]);
        }
        // 返回最长递增子序列的长度
        return maxLen;
    }
}
 
                

















