leetcode5955.摘水果(困难,周赛)
自己没思路,感觉下标处理太麻烦了。。。 有两种情况: 1.假设人向左走 y 步,然后回到原点,再向右走 x步。 2.假设人向右走 y 步,然后回到原点,再向左走 x步。 写法:枚举x的长度即为所有情况!!!
for (int x = 0; x <= k; ++x) { int y = (k - x) / 2; [startPos - x, startPos + y]的区间和(向右走 y 步,然后回到原点,再向左走 x步) [startPos - y, startPos + x]的区间和(向左走 y 步,然后回到原点,再向右走 x步) }
方法一:二分查找下标(用稀疏区间和处理)
class Solution { public: int maxTotalFruits(vector<vector<int>>& fruits, int startPos, int k) { vector<int> sum, pos; for (auto& each : fruits) { if (sum.empty()) sum.push_back(each[1]); else sum.push_back(sum.back() + each[1]); pos.push_back(each[0]); } int it1, it2; int ans = 0; for (int x = 0; x <= k; ++x) { int y = (k - x) / 2; //向下取整,才能保证向右走x步 //[startPos - x, startPos + y]区间和 it1 = lower_bound(pos.begin(), pos.end(), startPos - x) - pos.begin(); it2 = upper_bound(pos.begin(), pos.end(), startPos + y) - pos.begin() - 1; if (it2 != -1) { //这里必须加个判断,当it2等于-1时,表示该区间完全不存在,下面访问it2处的值时会越界!!! if (it1 == 0) ans = max(ans, sum[it2] - 0); else ans = max(ans, sum[it2] - sum[it1 - 1]); } //[startPos - y, startPos + x] it1 = lower_bound(pos.begin(), pos.end(), startPos - y) - pos.begin(); it2 = upper_bound(pos.begin(), pos.end(), startPos + x) - pos.begin() - 1; if (it2 != -1) { if (it1 == 0) ans = max(ans, sum[it2] - 0); else ans = max(ans, sum[it2] - sum[it1 - 1]); } } return ans; } };
方法二:计算出取值范围内所有的区间和
class Solution { public: int maxTotalFruits(vector<vector<int>>& fruits, int startPos, int k) { int _max = INT_MIN; for (auto& each : fruits) { _max = max(_max, each[0]); } vector<int> sum(_max + 1); //sum数组的下标为0-fruit[0]的最大值 _max++; for (auto& each : fruits) { sum[each[0]] = each[1]; } for (int i = 1; i < _max; ++i) { sum[i] = sum[i - 1] + sum[i]; } int ans = 0; //如果没有在区间内的话,返回0,不能初始化为int最小值 for (int x = 0; x <= k; ++x) { int y = (k - x) / 2; int ma, mi; if (startPos - x < _max) { //可能会出现左右端点都不在0-_max-1中的情况!!! ma = (startPos + y >= _max) ? sum[_max - 1] : sum[startPos + y]; mi = (startPos - x == 0 || startPos - x < 0) ? 0 : sum[startPos - x - 1]; ans = max(ans, ma - mi); } if (startPos - y < _max) { ma = (startPos + x >= _max) ? sum[_max - 1] : sum[startPos + x]; // mi = (startPos - y == 0 || startPos - y < 0) ? 0 : sum[startPos - y - 1]; // ans = max(ans, ma - mi); } } return ans; } };
易错点: 1:右端点可能会越界 2:左端点可能会越界 3:左右端点可能都会越界(因为startpos的取值范围不是0-position的最大值!!!) 4:ans初始化为0
上一篇:
IDEA上Java项目控制台中文乱码