一道算法题

题目

给出一组数,去除重复数字之后,得到的最大数字:

比如432345   去掉重复的位后有 4325 4235  3245  2345 这几种可能,输出最大的,也就是4325

代码:

#include <iostream>
#include <vector>
#include <map>
#include <time.h>
using namespace std;

#define FLAG  1111
void test(std::vector<unsigned int> num)
{
	//存放结果的向量
	std::vector<unsigned int> result;
	// num, pos List
	std::map<unsigned int, std::vector<unsigned int>> frequency;
	//计算0-9,在num中各自出现的频率
	for (unsigned int i = 0; i < num.size(); i++)
	{
		frequency[num[i]].push_back(i);
	}

	for (unsigned int pos = 0; pos < num.size(); pos++)
	{
		//如果数字已经在result里,就跳过
		if (num[pos] == FLAG) continue;

		//如果数字只出现了一次,那么直接将它附加到结果向量后,并继续。
		if (frequency[num[pos]].size() == 1)
		{
			result.push_back(num[pos]);
			continue;
		}

		//添加一个频率向量的拷贝
		std::map<unsigned int, std::vector<unsigned int>> frequencyCopy(frequency);

		//从频率不为1的元素开始,向后遍历。直到找到频率为1的元素。
		unsigned int begin = pos;
		unsigned int end = begin;
		for (unsigned int j = begin; j < num.size(); j++)
		{
			if (num[j] != FLAG && frequencyCopy[num[j]].size() <= 1) break;
			//重复元素的频率减1
			if (num[j] != FLAG)
			{
				auto it = frequencyCopy[num[j]].begin();
				frequencyCopy[num[j]].erase(it);
			}
			//继续向后搜索
			end++;
		}

		//找到最大的数字
		unsigned int max = num[begin], max_idx = begin;
		for (unsigned int j = begin; j <= end && j<num.size(); j++)
		{
			if (num[j] == FLAG || num[j] <= max) continue;

			max = num[j];
			max_idx = j;
		}

		//将最大值放入结果中
		result.push_back(max);
		//下一次迭代从max_idx+1开始(pos后面有个++)
		pos = max_idx;

		//重新更新数字出现的频率,处理过的数字设置为FLAG。
		frequency.clear();
		for (unsigned int j = max_idx+1; j < num.size(); j++)
			if (num[j] != FLAG && num[j] != max) frequency[num[j]].push_back(j);
			else num[j] = FLAG;
	}

	for (auto it = result.begin(); it != result.end(); it++)
		std::cout << *it;
	std::cout << std::endl;
}
int main() 
{
	std::vector<unsigned int> num;
	srand(time(0));

#define test2

#ifdef test1
	float v[] = {5,4,4,5,8};
	for (unsigned int i = 0; i < 5; i++)
		num.push_back(v[i]);
	for (auto it = num.begin(); it != num.end(); it++)
		std::cout << *it;
	std::cout << std::endl;
	test(num);
#endif // 1

#ifdef test2
	for (unsigned int times = 0; times < 100; times++)
	{
		for (unsigned int i = 0; i < 10; i++)
			num.push_back(rand() % 9 + 1);
		for (auto it = num.begin(); it != num.end(); it++)
			std::cout << *it;
		std::cout << std::endl;
		test(num);
		num.clear();
	}
#endif // test

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值