前言
思路及算法思维,指路 代码随想录。
题目来自 LeetCode。
day 35,连休两天~
题目详情
[1005] K次取反后最大化的数组和
题目描述
1005 K次取反后最大化的数组和
解题思路
前提:数组
思路:优先负数取反,未取到k次, 两两抵消后,将绝对值最小的正值取反。
重点:两次贪心。
代码实现
C语言
数组大小排序
注意临界导致数组溢出
int cmp(void *p1, void *p2)
{
return (*(int *)p1 > *(int *)p2);
}
int sum(int *nums, int numsSize)
{
int sum = 0;
for (int i = 0; i < numsSize; i++) {
sum += nums[i];
}
return sum;
}
int largestSumAfterKNegations(int* nums, int numsSize, int k) {
// 排序
qsort(nums, numsSize, sizeof(int), cmp);
// 取反, 优先负数取整
int zeroIdx = 0;
int curIdx = 0;
while ((k > 0) && (curIdx < numsSize) && (nums[curIdx] < 0)) {
nums[curIdx] = 0 - nums[curIdx];
curIdx++;
k--;
}
// 判断是否未取到k次, 两两抵消后,将绝对值最小的正值取反
if (k % 2 != 0) {
if ((curIdx == 0) || (numsSize == 1)) {
nums[0] = 0 - nums[0];
}
else if (curIdx == numsSize) {
nums[curIdx - 1] = 0 - nums[curIdx - 1];
}
else
{
if (nums[curIdx] <= nums[curIdx - 1]) {
nums[curIdx] = 0 - nums[curIdx];
}
else
{
nums[curIdx - 1] = 0 - nums[curIdx - 1];
}
}
}
return sum(nums, numsSize);
}
数组绝对值大小排序
int cmp(void *p1, void *p2)
{
return abs(*(int *)p1) < abs(*(int *)p2);
}
int sum(int *nums, int numsSize)
{
int sum = 0;
for (int i = 0; i < numsSize; i++) {
sum += nums[i];
}
return sum;
}
int largestSumAfterKNegations(int* nums, int numsSize, int k) {
// 按绝对值从大到小排序
qsort(nums, numsSize, sizeof(int), cmp);
// 将前k个负数取正
for (int j = 0; j < numsSize; j++) {
if (k == 0) {
break;
}
if (nums[j] < 0) {
nums[j] = 0 - nums[j];
k--;
}
}
// k未消耗完,将绝对值最小的元素取反,即数组最后一位
if (k % 2 == 1) {
nums[numsSize - 1] = 0 - nums[numsSize - 1];
}
// 求和
return sum(nums, numsSize);
}
[134] 加油站
题目描述
134 加油站
解题思路
前提:
思路:
重点:
代码实现
C语言
[135] 分发糖果
题目描述
135 分发糖果
解题思路
前提:
思路:
重点:
代码实现
C语言
今日收获
- 贪心算法:艰难的应用。