l 方法一
1 对N个无序的目标区间进行排序
2 顺序判断源区间是否在目标区间内
bool isOverlap([x, y], [x1, y1][x2,y2]...[xn,yn])
{
//以x为key进行升序排序,排序后x1<=x2<=x3<=..<=xn
sort([x1,y1][x2,y2]...[xn,yn]);
flg=0;
lastEnd=x1;
for (i=1;i<=n; i++)
{
if(flg==0)
{
//进入包含源区间的低端的目标区间
if(xi<=x && yi>=x)
{
flg = 1;
lastEnd= max(lastEnd, yi);
}
}
else
{
//判断区间是否中断
if(xi > lastEnd)
break;
lastEnd= max(lastEnd, yi);
//判断是否是源区间高端所在的目标区间
if(xi<=y && yi>=y)
{
flg = 2;
break;
}
}
}
return (flg == 2);
}
时间复杂度:排序O(nlogn)+ 遍历O(n)
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
/*
输入:
3 5 //第一行两个整数表示源区间
5 //第二行一个整数表示目标区间个数n
1 2 //接下来n行表示目标区间
2 3
3 5
6 7
7 8
输出:
true or false
*/
typedef struct _elemType {
int x, y;
}ElemType;
#define N 50 //最大区间数
#define LEN 100 //区间最大长度
#define MAX(a, b) ((a)>=(b)?(a):(b))
int comFun(const void *a, const void *b)
{
const ElemType *p1 = static_cast<const ElemType *>(a);
const ElemType *p2 = static_cast<const ElemType *>(b);
return (p1->x - p2->x);
}
bool isOverlap(int x, int y, const ElemType *p, int n)
{
int flg=0;
int lastEnd=p[0].y;
for (int i=0; i<n; i++)
{
if (flg == 0)
{
//找到包含源区间低端的目标区间
if (x>=p[i].x && x <=p[i].y)
{
flg = 1;
lastEnd = MAX(lastEnd, p[i].y);
}
}
else
{
//判断区间是否中断
if (p[i].x > lastEnd)
break;
lastEnd = MAX(lastEnd, p[i].y);
//if (y>=p[i].x && y<=p[i].y)
//if (y<=p[i].y)
if (y<=lastEnd)
{
flg = 2;
break;
}
}
}
return (flg == 2);
}
void main()
{
int x, y;
while(scanf("%d%d", &x ,&y) != EOF)
{
int n;
scanf("%d", &n);
ElemType des[N];
int i=0;
while (i<n)
{
scanf("%d%d", &des[i].x, &des[i].y);
i++;
}
qsort(des, n, sizeof(ElemType), comFun);
//test qort
/*printf("\n");
for (i=0; i<n; i++)
printf("%d %d\n", des[i].x, des[i].y);
*/
bool ret = isOverlap(x, y, des, n);
printf("%s\n", ret?"true":"false");
}
}
l 方法二
空间换时间
假设区间的最大长度为n,用一个int数组A[n]来表示区间,A[i] (1<=i<=n)表示区间,即区间[i, i+1]上长度为1的一个子区间,如果A[i]为零表示该子区间不包含在目标区间中,否则A[i]包含在目标区间中。更好的表达是:把N个无序的目标区间逐个投影到坐标轴上,然后遍历元区间所在的坐标轴部分,如果全为1表示,源区间包含在目标区间中。
bool isOverlap([x, y], [x1, y1][x2,y2]...[xn,yn])
{
int A[n] = {0};
for (i=1;i<=n; i++)
{
A[xi– yi] = 1;
}
for (i=x;i<=y; i++)
if(A[i]==0)
return0;
return 1;
}
时间复杂度O(n) 空间复杂度O(n)
#include <stdio.h>
/*
输入:
3 5 //第一行两个整数表示源区间
5 //第二行一个整数表示目标区间个数n
1 2 //接下来n行表示目标区间
2 3
3 5
6 7
7 8
输出:
true or false
*/
typedef struct _elemType {
int x, y;
}ElemType;
#define N 50 //最大区间数
#define LEN 100 //区间最大长度
bool isOverlap(int x, int y, const ElemType *p, int n)
{
int A[LEN] = {0};
int i;
for (i=0; i<n; i++)
{
for (int j=p[i].x; j<p[i].y; j++)
A[j] = 1;
}
for (i=x; i<=y; i++)
if (A[i] == 0)
return 0;
return 1;
}
void main()
{
int x, y;
while(scanf("%d%d", &x ,&y) != EOF)
{
int n;
scanf("%d", &n);
ElemType des[N];
int i=0;
while (i<n)
{
scanf("%d%d", &des[i].x, &des[i].y);
i++;
}
bool ret = isOverlap(x, y, des, n);
printf("%s\n", ret?"true":"false");
}
}
l 方法三
把方法二中的int数组换成位图,一个位表示一个单位长度为1的子区间,进一步降低空间复杂度
bool isOverlap([x, y], [x1, y1][x2,y2]...[xn,yn])
{
int A[(n+31)/32]= {0};
for (i=1;i<=n; i++)
{
A[xi– yi] = 1;
}
for (i=x;i<=y; i++)
if(A[i]==0)
return0;
return 1;
}
时间复杂度O(n) 空间复杂度O(n)
#include <stdio.h>
/*
输入:
3 5 //第一行两个整数表示源区间
5 //第二行一个整数表示目标区间个数n
1 2 //接下来n行表示目标区间
2 3
3 5
6 7
7 8
输出:
true or false
*/
typedef struct _elemType {
int x, y;
}ElemType;
#define N 50 //最大区间数
#define LEN 100 //区间最大长度
#define BITMASK 32
#define set_bit(a, n) (a[n/BITMASK] |= (1 << n%BITMASK))
#define read_bit(a, n) (a[n/BITMASK] & (1<<n%BITMASK))
bool isOverlap(int x, int y, const ElemType *p, int n)
{
int A[(LEN+31)/32] = {0};
int i;
for (i=0; i<n; i++)
{
for (int j=p[i].x; j<p[i].y; j++)
set_bit(A, j);
}
for (i=x; i<=y; i++)
if (read_bit(A, i) == 0)
return 0;
return 1;
}
void main()
{
int x, y;
while(scanf("%d%d", &x ,&y) != EOF)
{
int n;
scanf("%d", &n);
ElemType des[N];
int i=0;
while (i<n)
{
scanf("%d%d", &des[i].x, &des[i].y);
i++;
}
bool ret = isOverlap(x, y, des, n);
printf("%s\n", ret?"true":"false");
}
}
l 方法四
用目标区间来消减源区间,遍历完目标区间,如果把源区间消减完,则源区间在目标区间内。比较麻烦的一点是,可能会把源区间分成多个区间。
为方便出来,可以用链表来表示源区间,这样分离出一个区间就添加一个节点,如果某个区间被消减了,就删除相应的节点。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*
输入:
3 5 //第一行两个整数表示源区间
5 //第二行一个整数表示目标区间个数n
1 2 //接下来n行表示目标区间
2 3
3 5
6 7
7 8
输出:
true or false
*/
typedef struct _elemType {
int x, y;
}ElemType;
#define N 50 //最大区间数
#define LEN 100 //区间最大长度
bool isOverlap(int x, int y, const ElemType *p, int n)
{
typedef struct _tempType {
ElemType region;
struct _tempType *next;
}TempType;
TempType *head = (TempType *)malloc(sizeof(TempType));
TempType *q, *t, *pre;
head->region.x = x;
head->region.y = y;
head->next = NULL;
int i;
for (i=0; i<n; i++)
{
q = head, t=NULL, pre=head;
while (q)
{
//目标区间在源区间的中间 --> 分割区间
if (p[i].x > q->region.x && p[i].y < q->region.y)
{
t = (TempType *)malloc(sizeof(TempType));
t->region.x = q->region.x;
t->region.y = p[i].x;
q->region.x = p[i].y;
t->next = head;
head = t;
}
//目标区间在源区间之外
else if (p[i].y <= q->region.x || p[i].x >= q->region.y)
{
; //nothing tobe done
}
else
{
//分割左边
if (p[i].y <= q->region.y)
q->region.x = p[i].y;
else
q->region.y = p[i].x;
}
t = NULL;
if (q->region.x >= q->region.y)
{
t = q;
}
if (t)
{
q = q->next;
free(t);
if (t == head)
{
head = NULL;
}
else
{
pre->next = q;
}
}
else
{
pre = q;
q = q->next;
}
}
if (head == NULL)
return 1;
}
t = head;
while (t)
{
TempType *temp = t;
t = t->next;
free(temp);
}
return (head == NULL);
}
void main()
{
int x, y;
while(scanf("%d%d", &x ,&y) != EOF)
{
int n;
scanf("%d", &n);
ElemType des[N];
int i=0;
while (i<n)
{
scanf("%d%d", &des[i].x, &des[i].y);
i++;
}
bool ret = isOverlap(x, y, des, n);
printf("%s\n", ret?"true":"false");
}
}