Candy
There are N children standing in a line. Each child is assigned a rating value.
You are giving candies to these children subjected to the following requirements:
- Each child must have at least one candy.
- Children with a higher rating get more candies than their neighbors.
What is the minimum candies you must give?
分析: 主要问题是可以从左升序或者从右升序,如何取大值。
方法一:从左从右分别计算一次,对值校正。并计算出最大值。要保存中间初步的值,空间复杂度:O(n)
class Solution { public: int candy(vector<int> &ratings) { int n = ratings.size(); if(n == 0) return 0; int totalCandy = 0; int *getCandy = new int[n]; getCandy[0] = 1; for(int i = 1; i < n; ++i) if(ratings[i] > ratings[i-1]) getCandy[i] = getCandy[i-1] + 1; else getCandy[i] = 1; totalCandy += getCandy[n-1]; for(int i = n-1; i > 0; --i) { if(ratings[i-1] > ratings[i]) getCandy[i-1] = max(getCandy[i-1], getCandy[i]+1); totalCandy += getCandy[i-1]; } delete[] getCandy; return totalCandy; } };
方法二:从一个方向(此题从左),设置两个变量,通过计算升序长度,降序长度确定精确值。空间复杂度:O(1)
class Solution { public: int candy(vector<int> &ratings) { int LA = 0, LD = 0; // 利用降序长度和升序长度,来求结果。 bool decend = false; int totalCandy = ratings.size(); for(int i = 1; i < ratings.size(); ++i) { if(ratings[i-1] < ratings[i]) { if(LA == 0 || decend == true) LA = 2;//考虑情况:之前为降序,重新设置升序长度 else ++LA; LD = 0; decend = false; //升序时不需要知道之前降序长度。 totalCandy += (LA - 1); }else if(ratings[i-1] > ratings[i]) { decend = true; if(LD == 0) LD = 2; else ++LD; if(LD <= LA) totalCandy += (LD - 2); else totalCandy += (LD - 1); }else { LA = LD = 0; // 出现相同字符,则从第二个重复字符重新开始 } } return totalCandy; } };
Gas Station
There are N gas stations along a circular route, where the amount of gas at station i is gas[i]
.
You have a car with an unlimited gas tank and it costs cost[i]
of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.
Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.
Note: The solution is guaranteed to be unique.
方法一: 直接计算。(752ms)
class Solution { public: int canCompleteCircuit(vector<int> &gas, vector<int> &cost) { int n = gas.size(); if(n == 1) return gas[0] >= cost[0] ? 0 : -1; int tank = 0; for(int i = 0; i < n; ++i) { int j = i; for(; j < n; ++j) { tank += gas[j]; if(tank < cost[j]) break; tank = tank - cost[j]; } if(j == n) { for(j = 0; j < i; ++j) { tank += gas[j]; if(tank < cost[j]) break; tank = tank - cost[j]; } if(j == i) return i; } tank = 0; } return -1; } };
方法二:计算出每个站的油余量:(即从该站开始到下一站,还能剩余的油),将负数或者之前为非负数的值剔除。(20ms)
bool judge(int s, int e, int& cnt, vector<int> &gas) { for(int j = s; j < e; ++j) { cnt += gas[j]; if(cnt < 0) return false; } return true; } class Solution { public: int canCompleteCircuit(vector<int> &gas, vector<int> &cost) { int count = 0; for(int i = 0; i < gas.size(); ++i) gas[i] -= cost[i]; for(int i = 0; i < gas.size(); ++i) { if(gas[i] < 0) continue; else if(i > 0 && gas[i-1] >= 0) continue; if(judge(i, gas.size(), count, gas) && judge(0, i, count, gas)) return i; count = 0; } return -1; } };