训练营打卡Day34
思路
对数组进行排序,使得绝对值最大的数字排在最后。这样做的目的是,将绝对值最大的数字取相反数后,得到的增益会尽可能的大。 从前往后遍历数组中的每个数字,如果这个数字是负数且 k 还大于 0,则将这个数字取相反数,并将 k 减 1。 如果 k 为奇数,则将数组中最后一个数字取相反数。 计算数组中所有数字的和,并将其作为答案返回。
代码
class Solution {
public :
int largestSumAfterKNegations ( vector< int > & nums, int k) {
sort ( nums. begin ( ) , nums. end ( ) , [ ] ( const int & a, const int & b) {
return abs ( a) > abs ( b) ;
} ) ;
for ( auto & num: nums)
{
if ( num < 0 && k > 0 )
{
num *= - 1 ;
k-- ;
}
}
if ( k% 2 == 1 ) nums. back ( ) *= - 1 ;
int ans = 0 ;
for ( const auto & num: nums)
{
ans += num;
}
return ans;
}
} ;
思路
遍历整个加油站序列。 对于当前加油站,计算出从起点到这个加油站能否恰好加满油(total变量)。 同时计算出从上一个加油站到当前加油站能否恰好加满油(curSum变量)。 如果从上一个加油站到当前加油站加不满油,那么从下一个加油站开始作为起点。 遍历完整个序列后,如果total小于0,则返回-1。否则返回起点的位置(start变量)。
代码
class Solution {
public :
int canCompleteCircuit ( vector< int > & gas, vector< int > & cost) {
int curSum = 0 ;
int total = 0 ;
int start = 0 ;
for ( int i = 0 ; i < gas. size ( ) ; i++ )
{
total += gas[ i] - cost[ i] ;
curSum += gas[ i] - cost[ i] ;
if ( curSum < 0 )
{
start = i+ 1 ;
curSum = 0 ;
}
}
if ( total < 0 ) return - 1 ;
return start;
}
} ;
思路
先假设每个孩子都只得到了一块糖果,保存在candies数组里。 从前往后扫描ratings数组,如果当前孩子的评分比前一个孩子的评分高,则把当前孩子的糖果数量设为前一个孩子糖果数量+1。 从后往前扫描ratings数组,如果当前孩子的评分比后一个孩子的评分高,则把当前孩子的糖果数量设为后一个孩子糖果数量+1。(注意这里是取max,是因为在第2步中,可能已经把当前孩子的糖果数量设为了前一个孩子糖果数量+1) 最后计算candies的总和
代码
class Solution {
public :
int candy ( vector< int > & ratings) {
vector< int > candies ( ratings. size ( ) , 1 ) ;
for ( int i = 0 ; i < candies. size ( ) - 1 ; i++ )
{
if ( ratings[ i+ 1 ] > ratings[ i] ) candies[ i+ 1 ] = max ( candies[ i] + 1 , candies[ i+ 1 ] ) ;
}
for ( int i = candies. size ( ) - 2 ; i >= 0 ; i-- )
{
if ( ratings[ i] > ratings[ i+ 1 ] ) candies[ i] = max ( candies[ i+ 1 ] + 1 , candies[ i] ) ;
}
int ans = 0 ;
for ( const auto & cand: candies)
{
ans += cand;
}
return ans;
}
} ;