算法 - 动规10(Swift版本)

2 阅读1分钟

题目1:300.最长递增子序列

讲解
leetcode

class Solution {
    func lengthOfLIS(_ nums: [Int]) -> Int {
        // dp[i] 代表nums[i] 及以前的所有数字的 最长递增子序列个数 
        var dp = Array(repeating: 1, count: nums.count)
        // 最小是1
        var result = 1
        for i in 1..<nums.count {
            for j in 0..<i {
                if nums[i] > nums[j] {
                    dp[i] = max(dp[j] + 1, dp[i])
                }
            }
            result = max(result, dp[i])
        }
        return result
    }
}

题目2:674. 最长连续递增序列

讲解
leetcode

class Solution {
    func findLengthOfLCIS(_ nums: [Int]) -> Int {
        var dp = Array(repeating: 1, count: nums.count) 
        var result = 1
        for i in 1..<nums.count {
            if nums[i] > nums[i - 1] {
                dp[i] = dp[i - 1] + 1
            }
            result = max(result, dp[i])
        }
        return result
    }
}

题目3:718. 最长重复子数组

讲解
leetcode

class Solution {
    func findLength(_ nums1: [Int], _ nums2: [Int]) -> Int {
        // 定义二维动规方程
        // dp[i][j] 代表 nums1的i - 1以前  和 nums2的j - 1以前 最长重复子数组

        // 此处解释一下
        // 隔离第一行 第一列的目的是, 是为了让第一行 第一列可以参与进动规过程, 免去了复杂的手动初始化过程。
        // 否则 实际的初始化过程是:第一行 与nums1[0] 相同的初始化为1, 第一列 与nums2[0]相同的初始化为1, 否则初始化为0。 
        // 整个逻辑更通顺,但是写起来会麻烦很多。
        var dp = Array(repeating: Array(repeating: 0, count: nums2.count + 1), count: nums1.count + 1)
        var res = 0
        for i in 1...nums1.count {
            for j in 1...nums2.count {
                if nums1[i - 1] == nums2[j - 1] {
                    dp[i][j] = dp[i - 1][j - 1] + 1
                }
                res = max(res, dp[i][j])
            }
        }
        return res
    }
}