给定两个不相交的,相等的(大小为n
)集合(称为0
和1
),其值为1
到2n
我必须找到由特定遍历形成的最后一条边(一对顶点)。
遍历算法:
1
开始(这个值在哪个集合中无关紧要)3
,那么我将检查4
,5
,{ {1}},6
,...,7
,2n - 1
,2n
,1
)示例:
2
我能够以n = 5
Set "0": { 1, 2, 4, 8, 9 }
Set "1": { 3, 5, 6, 7, 10 }
Traversal path:
1 -> 3 -> 4 -> 5 -> 8 -> 10 -> 2 -> 6 -> 9 -> 7
Answer -> 9 and 7
复杂度解决这个问题。但我相信有更好的解决方案。
答案 0 :(得分:1)
您可以在O(nlogn)
current = 1
current value
的位置第4步详细说明:
假设您当前的值在array a
,而您正在array b
中搜索...
current value = 5
b = { 2 , 3 , 8 , 10}
^
如果您在数组b
中进行二元搜索,您将获得的位置为2
。所以现在 -
设置current value = 8
并将8标记为已访问
现在在step 2 and 3
中进行array a
,依此类推......
更新:
示例C ++实现:
#include <bits/stdc++.h>
using namespace std;
vector<int>right_a,right_b;
// Using union_find algorithm to find the next available value(which is not visited)
int find1(int x)
{
if(x==right_a[x])
return x;
right_a[x]=find1(right_a[x]);
}
int find2(int x)
{
if(x==right_b[x])
return x;
right_b[x]=find2(right_b[x]);
}
int main()
{
int i,j,k,l,m,n=5;
int a[]={1, 2, 4, 8, 9};
int b[]={3, 5, 6, 7, 10};
for(i=0;i<n;i++)
{
right_a.push_back(i);
right_b.push_back(i);
}
int cur=1,work_with;
if(a[0]==cur)
{
right_a[0]=1;
work_with=0;
}
else
{
right_b[0]=1;
work_with=1;
}
printf("%d",1);
int cnt=1;
while(cnt<2*n)
{
if(work_with==0)
{
// find first relative to actual value in array b
int ind=lower_bound(b,b+n,cur)-b;
if(ind==n)
ind=0;
ind=find2(ind);
int next=ind+1;
if(next==n)
next=0;
right_b[ind]=right_b[next]; // making current value visited
printf(" -> %d",b[ind]);
cur=b[ind];
work_with=1;
}
else
{
// find first relative to actual value in array a
int ind=lower_bound(a,a+n,cur)-a;
if(ind==n)
ind=0;
ind=find1(ind);
int next=ind+1;
if(next==n)
next=0;
right_a[ind]=right_a[next]; // making current value visited
printf(" -> %d",a[ind]);
cur=a[ind];
work_with=0;
}
cnt++;
}
printf("\n");
return 0;
}