【算法导论】2.3-7

【算法导论】2.3-7


给定n个元素的集合S和一个x,判断是否存在两个元素属于S,且他们的和为x,要求时间复杂度 Θ Θ Θ(nlgn)。


首先归并排序,时间复杂度 Θ Θ Θ(nlgn)
然后设置两个标兵从最小处和最大处相向前行,每次计算两元素和,若等于x,停止;若小于x,小标兵前进;若大于x,大标兵后退。直到两标兵相遇,或找到和为x的两元素。时间复杂度 Θ Θ Θ(n)
则总时间复杂度为 Θ Θ Θ(nlgn)。


代码如下:

/*练习2.3-7*/
#define _CRT_SECURE_NO_WARNINGS
#define MAXN 3200
#include
int ans = 0;
void merge(int a[], int p, int m, int q)
{
	int t, i, j, L[MAXN], R[MAXN], n1 = m - p + 1, n2 = q - m;
	for (i = p; i <= m; i++)
		L[i - p + 1] = a[i];
	for (i = m + 1; i <= q; i++)
		R[i - m] = a[i];
	L[n1 + 1] = R[n2 + 1] = MAXN;
	i = j = 1;
	for (t = p; t <= q; t++)
	{
		if (L[i] <= R[j])
		{
			a[t] = L[i];
			i++;
		}
		else
		{
			a[t] = R[j];
			j++;
		}
	}
	return;
}
void cal(int a[], int p, int q)
{
	int m = (p + q) / 2;
	if (p == q) return;
	cal(a, p, m);
	cal(a, m + 1, q);
	merge(a, p, m, q);
}
void main()
{
	int x, n, a[3200], i, j;
	scanf("%d", &n);
	for (i = 1; i <= n; i++)
		scanf("%d", &a[i]);
	scanf("%d", &x);
	cal(a, 1, n, x);
	i = 1;
	j = n;
	while (i < j)
	{
		if (a[i] + a[j] == x)
		{
			ans = 1;
			break;
		}
		else if (a[i] + a[j] < x)
			i++;
		else
			j--;
	}
	if (ans)
		printf("yes\n");
	else
		printf("no\n");
	getchar();
	getchar();
	return;
}

你可能感兴趣的:(读书笔记)