Chủ đề · Quy hoạch động 1 chiềuTrung bình
Dãy Con Tăng Dài NhấtLongest Increasing Subsequence
Hiểu bài
Cho mảng số nguyên nums. Tìm độ dài dãy con tăng nghiêm ngặt (strictly increasing subsequence) dài nhất. Dãy con không cần liên tiếp.
Ví dụ:
ts
nums = [10, 9, 2, 5, 3, 7, 101, 18]
output = 4 // dãy con: [2, 3, 7, 101] hoặc [2, 5, 7, 101]
nums = [0, 1, 0, 3, 2, 3]
output = 4 // dãy con: [0, 1, 2, 3]
nums = [7, 7, 7, 7]
output = 1 // chỉ 1 phần tử (tăng nghiêm ngặt, không có 2 phần tử bằng nhau)Điểm quan trọng: "dãy con" (subsequence) khác "dãy con liên tiếp" (subarray) — có thể bỏ qua phần tử giữa.
Cách cơ bản
O(n²) time, O(n) spacets
// DP O(n²) — the classic, good enough for interviews
function lengthOfLIS(nums: number[]): number {
const n = nums.length
if (n === 0) return 0 // empty array → LIS = 0 (avoids Math.max(...[]) = -Infinity)
// dp[i] = length of the LIS ending at index i
const dp = new Array(n).fill(1)
for (let i = 1; i < n; i++) {
for (let j = 0; j < i; j++) {
if (nums[j] < nums[i]) {
// nums[i] can extend the subsequence ending at nums[j]
dp[i] = Math.max(dp[i], dp[j] + 1)
}
}
}
return Math.max(...dp)
}Vì sao cách này chậm:
Với mỗi vị trí i, xét tất cả j < i để tìm phần tử nhỏ hơn có thể đứng trước.
Đủ tốt cho n ≤ 2500, nhưng với n = 10⁵ cần O(n log n).
Mở khoá để xem lời giải tối ưu, chạy thử từng bước và câu hỏi liên quan
Xem đầy đủ chạy thử từng bước, Big-O và trường hợp biên.