计蒜客 T1582:数组去重

问题

给你一个长度为 n 的数组 a,希望你可以去掉一些重复的元素。
但是有一些额外的要求:

  • 1.删除元素后,还需要保证原来的相对顺序。
  • 2.对于重复元素,希望可以保留最后出现的元素。

输入格式

第一行输入一个整数 n,表示数组 a 的长度。
接下来一行有 n 个整数。

输出格式

第一行输入一个整数,表示去重后剩下元素的个数。
依次输出剩下的元素。
输出时每行末尾的多余空格,不影响答案正确性。

解决方案

双重循环太慢,所以很自然考虑用高性能排序算法去重。可是排序会破坏调原来元素相对位置,所以用个结构体保存原下标。

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
struct number
{
	int val;
	int idx;
};
bool comp1(struct number n1, struct number n2)//按值排序
{
	if (n1.val < n2.val)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
bool comp2(struct number n1, struct number n2)//按下标排序
{
	if (n1.idx < n2.idx)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
int max(int a, int b)
{
	if (a > b)return a;
	else return b;
}


int main()
{
	//输入数据
	int n; cin >> n;
	struct number * arr = new struct number[n];
	for (int i = 0; i < n; i++)
	{
		cin >> arr[i].val;
		arr[i].idx = i;
	}



	//根据元素值排序
	sort(arr, arr+n, comp1);



	//值相同,保留下标最大的
	//利用栈去重
	stack<struct number> st;
	st.push(arr[0]);
	for (int i = 1; i < n; i++)
	{
		if (st.top().val == arr[i].val)//值相同
		{
			if (arr[i].idx>st.top().idx)//更靠后
			{
				//压入新元素
				st.pop();
				st.push(arr[i]);
			}
		}
		else//值不同,直接压入新元素
		{
			st.push(arr[i]);
		}
	}
	//经过前面的代码,栈中元素值互不相同
	//原数组重复值已被去掉仅保留靠后的值




	//将栈中元素导入数组中
	//uni:新数组(元素值互不相同)
	//unilen:新数组长度
	int unilen = st.size();
	struct number * uni = new struct number[unilen];
	for (int i = 0; i < unilen; i++)
	{
		uni[i] = st.top(); st.pop();
	}




	//下标由小到大排序
	sort(uni, uni + unilen, comp2);



	//元素值不重复,且重复值已被去掉仅保留靠后的值
	//输出结果
	cout << unilen << endl;
	if (unilen)
	{
		cout << uni[0].val;
	}
	for (int i = 1; i < unilen; i++)
	{
		cout << " " << uni[i].val;
	}
	getchar(); getchar();
	return 0;
}

你可能感兴趣的:(计蒜客 T1582:数组去重)