(Leetcode) [Dynamic programming] Longest increasing subsequence
Topic: Dynamic programming
Difficulty: Medium
Question
Given an integer array nums, return the length of the longest strictly increasing subsequence.
My first solution
int lengthOfLIS(vector<int>& nums) {
    int len = nums.size();
    int arr[len];
    for (int i=0; i<len; i++) {
        arr[i]=0;
    }
    for (int i=0; i<len; i++) {
        if (arr[i] == 0) { arr[i]=1; }
        else { continue; }
        vector<int>::iterator p = nums.begin()+i+1;
        int p_arr = i+1;
        vector<int>::iterator mark=p-1;
        int mark_arr = p_arr-1;
        for (p; p!=nums.end(); p++) {
            if (*p > *mark) {
                if (arr[p_arr] < arr[mark_arr]+1) {
                    arr[p_arr] = arr[mark_arr]+1;
                    mark_arr = p_arr;
                    mark = p;
                }
            }
            p_arr++;
        }
    }
    return *max_element(arr, arr+len);
}
์๋ฒฝํ ์๊ณ ๋ฆฌ์ฆ์ ๋ฐ๊ฒฌํ๋ค๊ณ ์๊ฐํ์ง๋ง, ์ด๊ฑด ํฐ ์ค์ฐ์ด์๋ค.
์ผ๋จ longest subsequence array์ ์์ ๊ฐฏ์๋ฅผ ์ ์ฅํ๊ธฐ ์ํ array๋ฅผ ํ๋ ๋ง๋ค์ด์ค๋ค (arr[]).
์ฒซ๋ฒ์งธ for loop์ sequential array์ ์์์ ์ ์ก๊ธฐ ์ํจ์ด๊ณ ,
๋๋ฒ์งธ loop์์  iterator๊ฐ ๋ ๊ฐ ์ฐ์ธ๋ค.
sequential array๋ฅผ ์ด์ด๋๊ฐ๊ธฐ ์ํด์  ๋ฐ๋ก ์ ์ element์ ํฌ๊ธฐ ๋น๊ต๋ฅผ ํด์ผํ๊ธฐ ๋๋ฌธ์ด๋ค.
๋น๊ตํ๋ ๊ณผ์ ์์ ์ ์ฝ์ ์ด ํ๋ ๋ฐ์ํ๋ค.
nums = [0 1 0 3 2 3]
arr =  [1 2 1 3 2 3] -> my algorithm (wrong)
arr =  [1 2 1 1 3 4] -> correct algorithm
nums์์ ๋ง๋ค ์ ์๋ ๊ฐ์ฅ ๊ธด subarray๊ฐ [0 1 2 3]์ด๋ค.
ํ์ง๋ง ๋ด ์ฝ๋์์ p iterator๊ฐ ์์๋๋ก ์์ง์ด๊ธฐ ๋๋ฌธ์, ๋ค์ ๋ ์์ ์ซ์๊ฐ ์์์๋ ์๋๋ฐ ๋น๊ต๋ฅผ ํ์ง ์์์
1 ๋ค์์ 2๊ฐ ์์์๋ ๋ถ๊ตฌํ๊ณ  2๋ณด๋ค ์์ ์๋ 3์ ์ฑํํด๋ฒ๋ฆฐ๋ค.
๊ทธ๋ฌ๋ฏ๋ก 2๋ ๋ฌด์๊ฐ ๋์ด๋ฒ๋ฆฐ๋ค.
๊ทธ๋ ๋ค๋ฉด ํด๊ฒฐ๋ฐฉ๋ฒ์ด ๋ฌด์์ด ์์๊น??
ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๋ชป ์ฐพ์์ ๊ฒฐ๊ตญ์ geeksforgeeks,,
My second solution: Dynamic programming
์ผ๋จ ์ฝ๋๋ ๋ณด์ง ์๊ณ ์ค๋ช (illustration)๋ง ์ฝ์ด๋ดค๋ค.
nums[] = {3, 10, 2, 11}
arr[] = {1, 1, 1, 1} (initialization)
1. arr[2] > arr[1] -> arr[2] = max(arr[2], arr[1]+1) = 2
2. arr[3] < arr[1] -> no change
3. arr[3] < arr[2] -> no change
4. arr[4] > arr[1] -> arr[4] = max(arr[4], arr[1]+1) = 2
5. arr[4] > arr[2] -> arr[4] = max(arr[4], arr[2]+1) = 3
6. arr[4] > arr[3] -> arr[4] = max(arr[4], arr[3]+1) = 3
p๋ผ๋ iterator๋ฅผ ๋๊ณ , ์ด์ค ๋ฃจํ๋ฅผ ์ด์ฉํด์ p ์ด์ ์ ์๋ ๋ชจ๋ element๋ค๊ณผ ๋น๊ต๋ฅผ ํ๊ฒ ํ๋ฉด ๋์ ์ฒซ๋ฒ์งธ solution์ ๋ฌธ์ ์ ์ด ํด๊ฒฐ์ด ๋๋ค.
int lengthOfLIS(vector<int>& nums) {
    int len = nums.size();
    int arr[len];
    for (int i=0; i<len; i++) {
        arr[i]=1;
    }
    if (len==1) { return 1; }
    vector<int>::iterator p;
    int p_arr = 1;
    for (p=nums.begin()+1; p != nums.end(); p++) {
        vector<int>::iterator mark;
        int mark_arr = 0;
        for (mark=nums.begin(); mark != p; mark++) {
            if (*p > *mark) {
                if (arr[p_arr] < arr[mark_arr]+1) {
                    arr[p_arr] = arr[mark_arr]+1;
                }
            }
            mark_arr++;
        }
        p_arr++;
    }
    return *max_element(arr, arr+len);
}
runtime: 163 ms (์์ 30%)
memory usage: 10.4 MB (์์ 30%)
time complexity: O(n^2)
๋ฌธ์  follow up์์ time complexity๊ฐ O(nlog n)์ธ ์๊ณ ๋ฆฌ์ฆ์ ์ฐพ์๋ณด๋ผ๊ณ ํ๋ค. ๋ ๋ชป ์ฐพ์.
Third solution: Lower bound based approach (time complexity of O(nlog n))
int lengthOfLIS(vector<int>& nums) {
    vector<int> arr;
    int len = nums.size();
    for (int i=0; i<len; i++) {
        // lower_bound searches for nums[i] by binary search.
        // if nums[i] doesn't exist in arr, p์ ์์น๋ nums[i]๋ณด๋ค ํฐ ๊ฐ ์ค์ ๊ฐ์ฅ ์์ ๊ฐ์ ๊ฐ๋ฅดํด.
        vector<int>::iterator p = lower_bound(arr.begin(), arr.end(), nums[i]);
        // p==nums.end() if all values of arr < nums[i]
        if (p==nums.end()) { arr.push_back(nums[i]); }
        // replace *p with ์์ ๋ณด๋ค ํฐ ๊ฐ ์ค ๊ฐ์ฅ ์์ ๊ฐ.
        // ๋ฐ๋ผ์ arr์ ๊ธธ์ด์๋ ๋ณํ๊ฐ ์์ง๋ง, ์์๊ฐ ๋ ์์ ๊ฐ์ผ๋ก ๋์ฒด๋์์ผ๋ฏ๋ก ๋ ํฐ ๊ฐ์ ์์๋ก ๊ฐ์ฆ๋ ๋ถ๋ถ ๋ฐฐ์ด๋ณด๋ค๋ ํญ์ ์ด๋์ด๋ค.
        else { *p = nums[i]; }
        return arr.size();
    }
}
Reference
https://www.geeksforgeeks.org/longest-increasing-subsequence-dp-3/ https://www.geeksforgeeks.org/c-program-for-longest-increasing-subsequence/
Leave a comment