LeetCode Candy 两种解法

Candy

There areNchildren standing in a line. Each child is assigned a rating value.

You are giving candies to these children subjected to the following requirements:

  • Each child must have at least one candy.
  • Children with a higher rating get more candies than their neighbors.

What is the minimum candies you must give?

这道题的关键:还是审题。感觉LeetCode的题目审题都难没审清楚题目就做,往往非常浪费时间。

还是列子最好说明问题:

比如我一开始考虑:1 2 3 3 3这样应该结果是 12,但是其实要求是8.

1 2 3 2 3 我以为结果是11,但是其实要求是9.

都看懂意思了吧。他这个要求其实是把题目”简化“了,反而害我们想多了的多做功夫了。

弄清楚题目之后就好办了。

下面是第一种解法:

#include<iostream>
#include<vector>

using namespace std;

class Solution {
public:
	int candy(vector<int> &ratings) {
		// IMPORTANT: Please reset any member data you declared, as
		// the same Solution instance will be reused for each test case.

		if(ratings.empty()) return 0;

		int n = ratings.size();

		vector<int> candyNum(n);
		//这里不能用for(auto x:candyNum) x=1;这样无法修改candyNum的值的。
		for(int i=0; i<n; i++)
		{
			candyNum[i] = 1;
		}

		for(int i=1; i<n; i++)
		{
			if(ratings[i-1]<ratings[i])
				candyNum[i] = candyNum[i-1]+1;
		}
		for(int i=n-2; i>=0; i--)
		{
			if(ratings[i+1]<ratings[i] && candyNum[i]<(candyNum[i+1]+1))
				candyNum[i] = candyNum[i+1]+1;
		}

		int sum = 0;
		for(int i=0; i<n; i++)
			sum += candyNum[i];

		return sum;
	}
};


int main()
{
	int a[] = {1,2,3,3,3};
	vector<int> va(a, a+5);
	Solution solu;
	cout<<solu.candy(va)<<endl;

	return 0;
}

其实vector创建的时候就已经为零的了,了解了这个属性之后可以省去第一个赋值循环,然后稍微改进一点,如下:

class Solution {
public:
	int candy(vector<int> &ratings) {
		// IMPORTANT: Please reset any member data you declared, as
		// the same Solution instance will be reused for each test case.

		if(ratings.empty()) return 0;

		int n = ratings.size();

		//利用vector属性,初始化为零
		vector<int> candyNum(n,0);

		for(int i=1; i<n; i++)
		{
			if(ratings[i-1]<ratings[i])
				candyNum[i] = candyNum[i-1]+1;
		}
		for(int i=n-2; i>=0; i--)
		{
			if(ratings[i+1]<ratings[i] && candyNum[i]<(candyNum[i+1]+1))
				candyNum[i] = candyNum[i+1]+1;
		}

		int sum = 0;
		for(int i=0; i<n; i++)
			sum += candyNum[i] + 1;
		//利用vector属性,初始化元素为零,candyNum存储的数量比实际数量少1,所以加1

		return sum;
	}
};

下面就用一个循环,不过嵌套了中间循环,也正因为这样,所以效率比较低,没accepted。不过也是不错的想法,所以贴出来分享下:

struct twoInt {
	int left;
	int right;
	twoInt():left(1),right(1){}
};

class Solution {
public:
	int candy(vector<int> &ratings) {
		// IMPORTANT: Please reset any member data you declared, as
		// the same Solution instance will be reused for each test case.

		if(ratings.empty()) return 0;

		int n = ratings.size();

		vector<twoInt> candyNum(n);

		for(int i=0; i<n; i++)
		{
			for(int k=i; k<n-1; k++)
			{
				if(ratings[k]<=ratings[k+1])
					break;
				candyNum[i].right++;
			}
			for(int k=i; k>0; k--)
			{
				if(ratings[k]<=ratings[k-1])
					break;
				candyNum[i].left++;
			}

			candyNum[i].left = 
				candyNum[i].left>=candyNum[i].right ? candyNum[i].left : candyNum[i].right;
		}

		int sum = 0;
		for(int i=0; i<n; i++)
			sum += candyNum[i].left;

		return sum;
	}
};



总结:

做LeetCode注重审题啊,这个是做出来的经验。而且不知道LeetCode是否是故意的,题目都不啰嗦,输出列子也不多给,读者没认真读懂题目是读者的责任了。


更新很简洁的程序,终极版本了,没法继续清晰和简洁了。

//2014-2-18 update
	int candy(vector<int> &ratings) 
	{
		int *A = new int[ratings.size()];
		A[0] = 1;
		for (int i = 1; i < ratings.size(); i++)
		{
			if (ratings[i] > ratings[i-1]) A[i] = A[i-1]+1;
			else A[i] = 1;
		}
		int ans = A[ratings.size()-1];
		for (int i = ratings.size() - 2; i >= 0 ; i--)
		{
			if (ratings[i] > ratings[i+1]) A[i] = max(A[i], A[i+1]+1);
			ans += A[i];
		}
		return ans;
	}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值