超時
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;
}
};