代码随想录第三十四天

#代码随想录第三十四天

1005.K次取反后最大化的数组和

给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次。(我们可以多次选择同一个索引 i。)

以这种方式修改数组后,返回数组可能的最大和。
翻转绝对值最大的负数,当都为正数时翻转最小的正数,或者不翻转任何数据,可以使得和最大
所以先进行一次从小到大的快排,然后使用双指针法得到根据绝对值的从小到大排列
代码如下:

void quick_sort(vector<int>& s, int l, int r)
	{
		if (l < r)
		{
			//Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
			int i = l, j = r;
			int x = s[l];
			while (i < j)
			{
				while (i < j && s[j] >= x) //s[j] >= x 从右向左找第一个小于x的数
					j--;
				if (i < j)
					s[i++] = s[j];

				while (i < j && s[i] < x) // s[i] < x从左向右找第一个大于等于x的数
					i++;
				if (i < j)
					s[j--] = s[i];
			}
			s[i] = x;
			quick_sort(s, l, i - 1); // 递归调用 
			quick_sort(s, i + 1, r);
		}
	}
	vector<int> sort1(vector<int>& nums)
	{
		quick_sort(nums, 0, nums.size() - 1);
		vector<int>result(nums.size());
		int i = 0;
		int j = nums.size() - 1;
		int k = nums.size() - 1;
		while (k>=0)
		{
			if (abs(nums[i])>abs(nums[j]))
			{
				result[k] = nums[i];
				i++;
			}
			else
			{
				result[k] = nums[j];
				j--;
			}
			k--;
		}
		return result;
	}
	//K次取反后最大化数组和
	int tanslateOfMaxSum(vector<int>& nums,int k)
	{	
		vector<int>re = sort1(nums);
		int i = re.size() - 1;
		while (i>=0)
		{
			if (re[i] < 0)
			{
				if (k > 0)
				{
					re[i] = -re[i];
					k--;
				}
				else
				{
					break;
				}
			}
			i--;
		}
		if (k > 0)
		{
			if (k % 2 == 1)
			{
				re[0] = -re[0];
			}
		}
		int sum = 0;
		for (int j=0;j<re.size();j++)
		{
			sum += re[j];
		}
		return sum;
	}

134. 加油站

在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。

你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。

如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。
每次都搜索到储油量大于耗油量的段,否则在重启下一段
代码如下

int station(vector<int>& gas,vector<int>&cost)
	{
		int curGas = 0;
		int allGas = 0;
		int start;
		for (int i=0;i<gas.size();i++)
		{
			curGas += gas[i] - cost[i];
			allGas += gas[i] - cost[i];
			if (curGas < 0)
			{
				start = i + 1;
				curGas = 0;
			}
			
		}
		if (allGas < 0)return-1;
		return start;
	}

135. 分发糖果

老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。

你需要按照以下要求,帮助老师给这些孩子分发糖果:

每个孩子至少分配到 1 个糖果。
相邻的孩子中,评分高的孩子必须获得更多的糖果。
那么这样下来,老师至少需要准备多少颗糖果呢?
先处理右侧比左侧大的情况,当右侧比左侧大,在前一个情况下多一,再从右向左,处理左侧比右侧大的,但是需要考虑前一次的情况
代码如下:

int candy(vector<int>& test)
	{
		vector<int>candies(test.size());
		candies[0] = 1;
		for (int i=1;i<test.size();i++)
		{
			if (test[i] > test[i - 1])candies[i] = candies[i - 1] + 1;
		}
		for (int i=test.size()-2;i>=0;i--)
		{
			if (test[i] > test[i + 1])
			{
				candies[i] = max(candies[i], candies[i + 1] + 1);
			}
		}
		int sum = 0;
		for (int i=0;i<candies.size();i++)
		{
			sum += candies[i];
		}
		return sum;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值