1.K 次取反后最大化的数组和
1.题目链接
2.算法原理详解
思路 :分情况讨论,设整个数组中负数的个数为m
m > k
:把前k
小负数,转化成正数m == k
:把所有的负数转化成正数m < k
:
先把所有的负数变成正数 讨论k - m
的奇偶性
偶数:直接忽略 奇数:挑选当前数组中最小的数,变成负数
2.代码实现
int largestSumAfterKNegations ( vector< int > & nums, int k)
{
int n = nums. size ( ) , m = 0 , minElem = INT_MAX, ret = 0 ;
for ( const auto & x : nums)
{
if ( x < 0 )
{
m++ ;
}
minElem = min ( minElem, abs ( x) ) ;
}
if ( m > k)
{
sort ( nums. begin ( ) , nums. end ( ) ) ;
for ( int i = 0 ; i < k; i++ )
{
ret += - nums[ i] ;
}
for ( int i = k; i < n; i++ )
{
ret += nums[ i] ;
}
}
else
{
for ( const auto & x : nums)
{
ret += abs ( x) ;
}
if ( ( k - m) % 2 )
{
ret -= 2 * minElem;
}
}
return ret;
}
2.按身高排序
1.题目链接
2.算法原理详解
解法一 :创建二元组
创建一个新的数组pair<int, string>
对新的数组排序 按照顺序把名字提取出来即可 解法二 :利用哈希表存下映射关系
先用哈希表存下映射关系<身高,名字>
对身高数组排序 根据排序后的结果,在哈希表里面找名字即可 缺点 :不可存重复的KEY值
解决方法 :map<int, string[]>
可以,但仍略显复杂 解法三 :对下标排序 (很常用的方法)
创建一个下标数组 仅需对下标数组排序 根据下标数组排序后的结果,找到原数组的信息
3.代码实现
vector< string> sortPeople ( vector< string> & names, vector< int > & heights)
{
int n = names. size ( ) ;
vector< int > index ( n) ;
for ( int i = 0 ; i < n; i++ )
{
index[ i] = i;
}
sort ( index. begin ( ) , index. end ( ) , [ & ] ( int i, int j)
{
return heights[ i] > heights[ j] ;
} ) ;
vector< string> ret;
for ( const auto & x : index)
{
ret. push_back ( names[ x] ) ;
}
return ret;
}
3.优势洗牌
1.题目链接
2.算法原理详解
思路 :
排序
nums1
直接排序nums2
下标排序 —> 为了不影响原数组的相对顺序 如果比不过,就去拖累对面最强的一个
3.代码实现
vector< int > advantageCount ( vector< int > & nums1, vector< int > & nums2)
{
int n = nums1. size ( ) ;
vector< int > index ( n) ;
for ( int i = 0 ; i < n; i++ )
{
index[ i] = i;
}
sort ( nums1. begin ( ) , nums1. end ( ) ) ;
sort ( index. begin ( ) , index. end ( ) , [ & ] ( int i, int j)
{
return nums2[ i] < nums2[ j] ;
} ) ;
vector< int > ret ( n) ;
int left = 0 , right = n - 1 ;
for ( const auto & x : nums1)
{
if ( nums2[ index[ left] ] < x)
{
ret[ index[ left++ ] ] = x;
}
else
{
ret[ index[ right-- ] ] = x;
}
}
return ret;
}