你可以这样做O(nlogn)
- 首先对数组和集合进行排序
current = 1
- 现在找到哪个数组包含 1,因为您必须从值 1 开始
- 现在
current value
使用 O(logn) 中的二进制搜索来搜索对面数组(附近)中的位置
- 找出左右附近值的差值,将当前值更改为差值最小的值
- 当然,设置您已经使用过的所有访问过的值。这样您就不会以相同的值工作两次
- 所以整体复杂度是O(nlogn)
第四步细化:
假设您的当前值在array a
并且您正在搜索array b
...
current value = 5
b = { 2 , 3 , 8 , 10}
^
如果你在数组b
中进行二进制搜索,你会得到的位置是2
. 所以现在——
设置current value = 8
并将 8 标记为已访问。
现在做step 2 and 3
inarray 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;
}