【代码随想录】刷题笔记Day51

前言

  • 周六刷题,闻所未闻吧兄弟,不用开组会简直太爽啦

300. 最长递增子序列 - 力扣(LeetCode)

  • 子序列系列问题,用动态规划解决
  • dp[i]含义
    • 表示i之前包括i的以nums[i]结尾的最长递增子序列的长度
  • 递推公式
    • j从0到i-1各个位置的最长升序子序列 + 1 的最大值
    • if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1);
  • 初始化
    • dp[i] = 1,长度都为1
  • 遍历顺序
    • 从前到后,i从1到size-1,j从0到i-1
  • 结果
    • 更新dp的时候更新最大值(不是取dp[size-1])
  • class Solution {
    public:
        int lengthOfLIS(vector& nums) {
            int len = nums.size();
            vector dp(len, 1);
            int res = 1;  // 答案最少也有1
            for(int i = 1; i < len; i++){
                for(int j = 0; j < i; j++){
                    if(nums[i] > nums[j]){
                        dp[i] = max(dp[j] + 1, dp[i]);
                    }
                    res = max(res, dp[i]);  // 取长的子序列
                }
            }
            return res;
        }
    };

674. 最长连续递增序列 - 力扣(LeetCode) 

  • 贪心法

    • 遇到nums[i] > nums[i - 1]的情况,count++,否则count为1,记录count的最大值
    • class Solution {
      public:
          int findLengthOfLCIS(vector& nums) {
              int res = 1;  // 连续子序列最少是1
              int count = 1;
              for(int i = 1; i < nums.size(); i++){
                  if(nums[i] > nums[i - 1]) count++;  // 连续记录
                  else count = 1;  // 不连续,从头开始
                  res = max(res, count);  // 更新最长连续
              }
              return res;
          }
      };
  •  动规法

    • dp[i]:以下标i为结尾的连续递增的子序列长度为dp[i]
    • if(nums[i] > nums[i - 1])  dp[i] = max(dp[i - 1] + 1, dp[i]);

    • class Solution {
      public:
          int findLengthOfLCIS(vector& nums) {
              int len = nums.size();
              vector dp(len, 1);
              int res = 1;
              for(int i = 1; i < len; i++){
                  if(nums[i] > nums[i - 1]){  // 连续记录
                      dp[i] = max(dp[i - 1] + 1, dp[i]);
                  }
                  res = max(dp[i], res);
              }
              return res;
          }
      };

 718. 最长重复子数组 - 力扣(LeetCode)

  • dp[i][j]含义
    • 以下标i - 1为结尾的A,和以下标j - 1为结尾的B,最长重复子数组长度为dp[i][j]
    • 不定义下标i是因为初始化更方便,[-1]直接初始为0
  • 递推公式
    • 当A[i - 1] 和B[j - 1]相等的时候,dp[i][j] = dp[i - 1][j - 1] + 1;
  • 初始化
    • dp[i][0] 和dp[0][j]初始化为0
  • 遍历顺序
    • 两层for遍历两个数组,记录最大值
  • class Solution {
    public:
        int findLength(vector& nums1, vector& nums2) {
            vector> dp (nums1.size() + 1, vector(nums2.size() + 1, 0));
            int result = 0;
            for (int i = 1; i <= nums1.size(); i++) {
                for (int j = 1; j <= nums2.size(); j++) {
                    if (nums1[i - 1] == nums2[j - 1]) {
                        dp[i][j] = dp[i - 1][j - 1] + 1;
                    }
                    if (dp[i][j] > result) result = dp[i][j];
                }
            }
            return result;
        }
    };

后言

  • 好耶,刚好刷完,找女朋友玩耍去咯~ 

你可能感兴趣的:(代码随想录刷题笔记,笔记,leetcode,数据结构,算法,职场和发展)