leetcode之每日一题767重构字符串之最大堆和c++11lambda解决问题

题目描述:

给定一个字符串S,检查是否能重新排布其中的字母,使得两相邻的字符不同。

若可行,输出任意可行的结果。若不可行,返回空字符串。

示例 1:

输入: S = "aab"
输出: "aba"

示例 2:

输入: S = "aaab"
输出: ""

刚看到这个题,就觉得直接用一个数组记录下S每个字符出现的次数,不可以重构的原因无非就是一个字符出现的次数大于一个阈值,若S的长度为偶数时,阈值为长度的一半,若S的长度为奇数时,则阈值为长度加1的一半,超过这个阈值则不能重构。能重构的情况下,找到出现次数最大的,每次先把他加到结果result中,在加其他的。直到result的长度等于S的长度。结果超时了,代码如下:

class Solution {
public:
    string reorganizeString(string S) {
      //将S中每个字符存到数组中
	int n = S.size();
	vector<int>temp(26,0);
	int maxx = 0;
	int index = 0;
	for (int i = 0; i < n; i++)
	{
		temp[S[i] - 'a']++;
		maxx = max(maxx, temp[S[i] - 'a']);
		if (temp[S[i] - 'a'] > maxx)
		{
			maxx = temp[S[i] - 'a'];
			index = i;
		}
		
	}
	if (maxx > (n / 2)&&(n%2==0))
	{
		return "";
	}
	string result = "";
	while (result.size() <n)
	{
		for (int i = 0; i < 26; i++)
		{
			if (temp[i] != 0&&i!=index)
			{
				result += index + 'a';
				result += i + 'a';
				temp[index]--;
				temp[i]--;
			}
		}
	}
	
	return result;
    }
};

然后又想到是每次都要选出出现次数最大的,其实就是相当于最大堆,然后经过改进,用代码堆来实现,其中用到了c++11中lambda表达式来进行判断。代码如下:

class Solution {
public:
    string reorganizeString(string S) {
    //将S中每个字符存到数组中
	int n = S.size();
	vector<int>temp(26,0);
	int maxx = 0;
	int index = 0;
	for (int i = 0; i < n; i++)
	{
		temp[S[i] - 'a']++;
		maxx = max(maxx, temp[S[i] - 'a']);
		if (temp[S[i] - 'a'] > maxx)
		{
			maxx = temp[S[i] - 'a'];
			index = i;
		}
		
	}
	if (maxx > ((n+1) / 2)&&(n%2==0))
	{
		return "";
	}else if (maxx > (n + 1) / 2 && (n % 2 == 1))
	{
		
		return "";
	}
	auto cmp = [&](const char& letter1, const char& letter2) {
		return temp[letter1 - 'a'] < temp[letter2 - 'a'];
	};
	priority_queue<char, vector<char>, decltype(cmp)>queue{ cmp }; 
	for (char c = 'a'; c <= 'z'; c++) {
		if (temp[c - 'a'] > 0) {
			queue.push(c);
		}
	}

	string result = "";
	while (queue.size() >1)
	{
		char letter1 = queue.top(); queue.pop();
		char letter2 = queue.top(); queue.pop();
		result += letter1;
		result += letter2;
		int index1 = letter1 - 'a', index2 = letter2 - 'a';
		temp[index1]--;
		temp[index2]--;
		if (temp[index1] > 0)
		{
			queue.push(letter1);
		}
		if (temp[index2] > 0)
		{
			queue.push(letter2);
		}
	}
	if (queue.size() > 0)
	{
		result += queue.top();
	}
	
	return result;
    }
};

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值