分治算法—work2_2_14—删除相同元素

题目:

算法思路:

基本思想是归并排序的思想,细节上有差异。

在进行两个有序数组合并的时候,查找重复的字符,如果重复,其中一个指针移动,一个数只存一次,由于数组的长度发生了变化 ,需要返回删除重复字符后的数组最右边界,数组在合并时只对左右边界内的数据进行处理 。

时间复杂度O(nlogn)

 

int remove(int a[], int b[], int l, int lm, int rm, int r)   //l前半段的左边界,lm前半段的右边界 ,
{				                                           	//rm后半段的左边界,r后半段的右边界 
	int i = l; 
	int j = rm;
	int k = l;
	while (i <= lm && j <= r)     //在数组范围内 
	{
		if (a[i] < a[j])
		{
			b[k++] = a[i++];
		}
		else if (a[i] > a[j])
		{
			b[k++] = a[j++];
		} 
		else
		{
			j++;              //相等时,只移动指针不存储 
		}
	}
	while (i <= lm)
	{
		b[k++] = a[i++];      //存储剩下的数 
	}
	while (j <= r)
	{
		b[k++]  = a[j++];        //存储剩下的数 
	}
	for (i = l; i < k; i++)     //数组复制 
	{
		a[i] = b[i];
	}
	return k - 1;                 //返回合并后的右边界 
}

int removeall(int a[], int b[], int l, int r)   //划分->递归->合并 
{
	int m = l + (r - l) / 2;
	if (l < r) 
	{
		int lm = removeall(a, b, l, m);         //得到前半段的右边界 
		r = removeall(a, b, m + 1, r);         //得到后半段的右边界
		r = remove(a, b, l, lm, m + 1, r);        //合并前后两段 
	}
	return r;
}

int main()
{
	int a[] = {1, 2, 3, 4, 5, 1, 3, 5, 7, 9};
	int b[12];
	int r = removeall(a, b, 0, 9);
	for (int i = 0; i <= r; i++)
	{
		cout << a[i] << ' '; 
	}
	return 0;
}

 

方法一 (分治法)

类似于归并排序的递归方法,但在combine阶段合并两个有序子序列的merge操作中,同时还删除重复的元素,即对分别位于两个子序列中相等的元素只保留一个。Merge算法的时间复杂度仍为O(n)。算法的总体复杂度为O(nlogn)。

方法二

首先采用一个O(nlogn)复杂度的排序算法对数组进行排序;然后在数组元素有序的基础上,可以使用一个O(n)复杂度的算法删除数组中的重复元素。算法的总体复杂度为O(nlogn)。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值