leetcode 135. Candy

超時

class Solution {
public:
    using It = vector<int>::iterator;
    int candy(vector<int>& ratings) {
        int n = ratings.size();
        if (n == 0) return 0;
        vector<int> candys(n + 2, 0);

        return reSolver(ratings, 0, n - 1, -1, candys, true);

    }

    // if dir == 0 forward;
    // if dir == 1 backward;
    // [begin, end]

    int reSolver(vector<int>& ratings, int begin, int end, int lastMinId, vector<int>& candys, bool forward) {
        int n = ratings.size();
        if(begin > end) return 0;
        int minId;
        if (forward) {
            minId = begin;
            for (int i = begin + 1; i <= end; ++i) {
                if (ratings[i] < ratings[minId])
                    minId = i;
            }
        } else {
            minId = end;
            for (int i = end - 1; i >= begin; --i) {
                if (ratings[i] < ratings[minId])
                    minId = i;
            }
        }

        if (candys[minId] == 0 && candys[minId + 2] == 0)
            candys[minId + 1] = 1;
        else if (candys[minId] != 0 && candys[minId + 2] != 0) {
            if (ratings[minId] > ratings[minId + 1] && ratings[minId] > ratings[minId - 1]) // smaller in both side
                candys[minId + 1] = max(candys[minId], candys[minId + 2]) + 1;
            else { // smaller if one side
                int tmpId = minId + 1; // mark the smaller
                if (ratings[minId - 1] < ratings[minId]) {
                    tmpId = minId - 1;
                }
                candys[minId + 1] =  candys[tmpId + 1] + 1;
            }
        } else {

            // candys[minId + 2] = 0;
            int tmpId = minId + 1;
            if (candys[minId] != 0)
                tmpId = minId - 1;


            if (ratings[minId] == ratings[tmpId])
                candys[minId + 1] = 1;
            else
                candys[minId + 1] =  max(candys[minId], candys[minId + 2]) + 1;
        }
       // cout << minId << " " << candys[minId + 1] << endl;
        return candys[minId + 1] + reSolver(ratings, begin, minId - 1, minId, candys, false) + reSolver(ratings, minId + 1, end, minId, candys, true);


    }

};

優化了不少還是超時

class Solution {
public:
    using It = vector<int>::iterator;
    int candy(vector<int>& ratings) {
        int n = ratings.size();
        if (n == 0) return 0;
        vector<int> candys(n + 2, 0);

        return reSolver(ratings, 0, n - 1, -1, candys, true);

    }

    // if dir == 0 forward;
    // if dir == 1 backward;
    // [begin, end]

    int reSolver(vector<int>& ratings, int begin, int end, int lastMinId, vector<int>& candys, bool forward) {
        int n = ratings.size();
        if(begin > end) return 0;
        int minId;
        if (forward) {
            minId = begin;
            for (int i = begin + 1; i <= end; ++i) {
                if (ratings[i] < ratings[minId])
                    minId = i;
            }
        } else {
            minId = end;
            for (int i = end - 1; i >= begin; --i) {
                if (ratings[i] < ratings[minId])
                    minId = i;
            }
        }

        // 找等
        int tmpId;
        if (forward) tmpId = minId - 1;
        else tmpId = minId + 1;

        if (ratings[tmpId] == ratings[minId])  // 等   小(含0)
            candys[minId + 1] = candys[2 * minId - tmpId + 1] + 1; // 另一邊加一
        else // 小(含0)   小(含0)
            candys[minId + 1] = max(candys[minId], candys[minId + 2]) + 1;

       // cout << minId << " " << candys[minId + 1] << endl;
        return candys[minId + 1] + reSolver(ratings, begin, minId - 1, minId, candys, false) + reSolver(ratings, minId + 1, end, minId, candys, true);


    }

};

居然更差 ,畢竟之前的方法有些是用不着算的

class Solution {
public:
    using It = vector<int>::iterator;
    int candy(vector<int>& ratings) {
        int n = ratings.size();
        if (n == 0) return 0;
        vector<int> candys(n + 2, 0);
        vector<vector<int> > dp (n, vector<int>(n, 0));
        // len = 1;
        for (int i = 0; i < n; ++i) {
            dp[i][i + 1 - 1] = i;
        }

        // len >= 2;
        for (int len = 2; len <= n; ++len) {

            for (int start = 0; start + len <= n; ++start) {

                if (ratings[start + len - 1] < ratings[dp[start][start + len - 1 - 1]]) 
                    dp[start][start + len - 1] = start + len - 1;
                else 
                    dp[start][start + len - 1] = dp[start][start + len - 1 - 1];
            }

            for (int start = n - 1; start - len >= -1; --start) {

                if (ratings[start - len + 1] < ratings[dp[start][start - (len - 1) + 1]]) 
                    dp[start][start - len + 1] = start - len + 1;
                else 
                    dp[start][start - len + 1] = dp[start][start - len + 1 + 1];
            }
        }

        return reSolver(ratings, 0, n - 1, candys, dp, true);

    }

    // [begin, end]

    int reSolver(vector<int>& ratings, int begin, int end, vector<int>& candys, vector<vector<int> >& dp, bool forward) {

        int n = ratings.size();
        if(begin > end) return 0;
        int minId;
        int tmpId; // 找等
        if (forward) {
            minId = dp[begin][end];
            tmpId = minId - 1;
        } else {
            minId = dp[end][begin];
            tmpId = minId + 1;
        }


        if (ratings[tmpId] == ratings[minId])  // 等   小(含0)
            candys[minId + 1] = candys[2 * minId - tmpId + 1] + 1; // 另一邊加一
        else // 小(含0)   小(含0)
            candys[minId + 1] = max(candys[minId], candys[minId + 2]) + 1;

       // cout << minId << " " << candys[minId + 1] << endl;
        return candys[minId + 1] + reSolver(ratings, begin, minId - 1, candys, dp, false) + reSolver(ratings, minId + 1, end, candys, dp, true);

    }
};

參考後, 其實也想過正反兩次遍歷, 忘了只加不減

class Solution {
public:
    int candy(vector<int>& ratings) {
        int n = ratings.size();
        if (n <= 1) return n;
        vector<int> candys(n, 1);
        for (int i = 1; i != n; ++i) {
            if (ratings[i] > ratings[ i - 1])
                candys[i] = candys[i - 1] + 1;
        }

        for (int i = n - 2; i >= 0; --i) {
            if (ratings[i] > ratings[i + 1])
                candys[i] = max(candys[i], candys[i + 1] + 1);
        }

        return accumulate(cbegin(candys), cend(candys), 0);
    }
};

參考後

explain http://www.allenlipeng47.com/blog/index.php/2016/07/21/candy/

class Solution {
public:
    int candy(vector<int>& ratings) {
        int size = ratings.size();

        int pre = 1;
        int ret = 1;
        int countDown = 0;

        for (int i = 1; i < size; ++i) {
            if (ratings[i] >= ratings[i - 1]) {
                 if (countDown > 0) {
                        ret += (countDown + 1) * countDown / 2;
                        if (pre <= countDown) {
                            ret += countDown + 1 - pre;
                        }
                        countDown = 0;
                        pre = 1;
                }
                if (ratings[i] > ratings[i - 1]) {

                    ++pre;
                }
                else // 相等
                    pre = 1;

                ret += pre;

            } else {
                ++countDown; 
            }
        }

         if (countDown > 0) {
            ret += (countDown + 1) * countDown / 2;
            if (pre <= countDown) {
                ret += countDown + 1 - pre;
            }

        }

        return ret;

    }
};
發佈了227 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章