1005. K 次取反后最大化的数组和
按照绝对值大小降序排序,然后将负值变正,如果所有负值都正了,但是还有k余量且为奇数,那就将绝对值最小值(最后一个元素)取反,否则直接结束。
class Solution {
public:
// 类内调用函数指针静态(猜的)
static bool cmp(int a, int b){
return abs(a)>abs(b);
}
int largestSumAfterKNegations(vector<int>& nums, int k) {
// 按照绝对值从大到小排序
sort(nums.begin(), nums.end(), cmp);
for (int i = 0; i<nums.size(); i++) {
if (k>0 && nums[i]<0){
nums[i] *= -1;
k--;
}
}
int res = 0;
if (k%2 == 1){
nums[nums.size()-1] *= -1;
}
for (auto i:nums){
res += i;
}
return res;
}
};
从左往右,找右边比左边大的,给右边赋值为左边加一。从右往左,找左边比右边大的,给左边赋值 右边加一与 左边本身 的较大值(兼顾左边)。
class Solution {
public:
int candy(vector<int>& ratings) {
int res = 0;
vector<int> candyVec(ratings.size(), 1);
for (int i = 1; i<ratings.size(); i++) {
if (ratings[i]>ratings[i-1]) {
candyVec[i] = candyVec[i-1]+1;
}
}
for (int i = ratings.size()-2; i >= 0; i--) {
if (ratings[i] > ratings[i+1]) {
candyVec[i] = max(candyVec[i], candyVec[i+1]+1);
}
}
for (auto i : candyVec){
res += i;
}
return res;
}
};
用数组前缀和,从零开始找出发点,如果当前前缀和小于零,那么前面的都不能作为出发点,直接从后一个再出发。最后如果总和小于零就无法找到结果,返回-1。
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int totalSum = 0;
int curSum = 0;
int start = 0;
for (int i = 0; i<gas.size(); i++) {
totalSum += (gas[i] - cost[i]);
curSum += (gas[i] - cost[i]);
if (curSum < 0) {
start = i+1;
curSum = 0;
}
}
if (totalSum < 0) return -1;
return start;
}
};