close

今天去面試又被電了

可悲如我,實力差找不到好工作,只好回來寫個leetcode

結果又被這題電了...

看來會被電的到哪都會被電啊=ˇ=

 

好吧那來看題目吧

Given an unsorted array of integers, find the length of longest increasing subsequence.

Example:

Input: [10,9,2,5,3,7,101,18]
Output: 4 
Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4. 

那就... 直接解吧XD

 

Sol:

先說結論,我完全不知道怎麼辦,最後是直接去看答案了

不過講道理應該是要有點頭緒才對,所以我先來記錄一下我大概的想法

首先第一個想到的是把所有可能都找出來

...話是這麼說,不過要我找出全部的可能,我也不太知道怎麼找

再來想到要用Dynammic Programming的方式做,但也不知從何下手...

 

看完答案就證明一件事情,就是我都只學半套的

這兩種做法都是可行的,我們就來看看吧

首先是brute force的方法:

int lengthOfLIS(vector<int>& nums) {
        return helper(nums, INT_MIN, 0);
    }
    
    int helper(vector<int>& nums, int prev, int curpos)
    {
        if (curpos == nums.size())
            return 0;
        
        int len_taken = 0;
        
        if (nums[curpos] > prev)
        {
            len_taken = 1 + helper(nums, nums[curpos], curpos+1);  // 如果有包含現在這個數值,那麼就把回傳的值加1,並更改prev的值,計算後面的結果
        }
        
        int len_nottaken = helper(nums, prev, curpos+1);  // 不管有沒有包含現在的值,後面計算的結果還是要算
        
        return max(len_taken, len_nottaken);
    }

總之就是檢查這個數值是不是要被納入這次的計算當中,要的話就加1然後算接下來的

然後如果不納入的話... 還是要算接下來的啊XD

不然你的計算就直接斷在這邊了不是嗎,後面的還是要算啊XD

總之不管有沒有要納入現在這個值,後面的結果都是要算的,只是prev的值改變了而已

所以這個方法,非常的恐怖...

 

其實我看完答案之後,反而還覺得DP的方法比較好懂

那我們就來看Dynammic Programming的做法:

    int lengthOfLIS(vector<int>& nums) {
        if (nums.empty())
            return 0;
        
        int memo[nums.size()];
        for (int i = 0; i < nums.size(); ++i)
        {
            memo[i] = 1;
        }
        
        int LIS = 1;
        
        for (int i = 1; i < nums.size(); ++i)
        {
            int maxval = 0;
            
            for (int j = 0; j < i; ++j)
            {
                if (nums[i] > nums[j])
                {
                    maxval = max(maxval, memo[j]);
                }
            }
            
            memo[i] = maxval + 1;
            LIS = max(LIS, memo[i]);
        }
        
        return LIS;
    }

反正Dynammic Programming的重點就是... 這個memo到底是存什麼的

在這題裡面呢,memo[i]就是表示:從0到i之間最大的LIS

所以如果要算memo[j]的話,會等於多少呢?

 

memo[j] = max(memo[i]) + 1, 0 <= i < j , memo[j] > memo[i]

 

乾這到底誰想的... 真的天才ㄟ= =

簡單說memo[i]就是到i這個為止最大的LIS,如果memo[j] > memo[i]的話memo[j]就是memo[i]+1這樣

所以只要找出符合memo[j] > memo[i]這個條件中最大的memo[i],然後把它加1就是memo[j]了

 

好吧我大概了解了,但是後來又看到一個更神奇的作法

https://leetcode.com/problems/longest-increasing-subsequence/discuss/74855/Short-C%2B%2B-STL-based-solution%3A-O(n-log-n)-time-O(1)-space-with-explanation

我就不解釋了,這些人真的是跟鬼一樣ㄟ

 

看來還真的是... 充滿進步空間啊XD

持續練習努力吧~

arrow
arrow
    全站熱搜

    頁頁頁六滴 發表在 痞客邦 留言(0) 人氣()