面试问题:在内存中替换两个数组的位置

时间:2011-01-19 14:05:05

标签: arrays

给定两个连续的数组AB。它们看起来像

int AandB[] = {a1,a2,...,am,b1,b2,...,bn};

您需要编写一个程序来切换内存中数组AB的顺序,以便B出现在A之前。在我们的示例中,AandB应该变为

int AandB[] = {b1,b2,...,bn,a1,...,am};

最有效的方法是什么?

5 个答案:

答案 0 :(得分:6)

三个数组反转:

(a1 a2 a3 a4 a5 b1 b2 b3)
 b3 b2 b1 a5 a4 a3 a2 a1
(b3 b2 b1)a5 a4 a3 a2 a1
 b1 b2 b3 a5 a4 a3 a2 a1
 b1 b2 b3(a5 a4 a3 a2 a1)
 b1 b2 b3 a1 a2 a3 a4 a5

使用带有开始和结束的“rev”函数表示:

rev(AandB, 0, n+m)
rev(AandB, 0, m)
rev(AandB, m, n)

对于rev(为清晰起见省略类型等):

rev(x, i, j) {
    j--; // j points to one after the subarray we're reversing
    while (i < j) {
        tmp = x[i];
        x[i] = x[j];
        x[j] = tmp;
        i++;
        j--;
    }
}

答案 1 :(得分:3)

我的回答:

首先,我假设wlog为m<n

由于每个排列都可以分解为不相交的循环,因此排列可以a1,...,am,b1,..,bnb1,..,bn,a1,...,am。由于给定了索引i,因此很容易计算p(i)(假设wlog为m<n,如果为i<=m,则为p(i)=n+i,如果i>m 1}}我们有p(i)=i-m)。

我们可以从AandB[i]开始,将其值移至p(i)=j,然后取AandB[j]中的值并将其移至p(j)等。由于排列可以是分解成不相交的周期,我们最终会进入i

我们只需要跟踪我们已经移动的元素。有可能证明在我们的情况下,排列中没有循环将包含A的两个连续元素,所以我认为它足以跟踪我们订购了A的多少元素。

另一个效率不高的简单选择是注意到这一点 给定{a1,...,am,b1,...bn},可以将a1..am替换为b(n-m)..b(n),获取{b(n-m)...b(n),b(1)..b(m),a1..am}。现在通过递归,为数组的第一个n元素解决相同的问题。但这可能效率不高。

还有一些细节我省略了,但无论如何,面试官告诉我这不是可行的方法,并且有一些非常聪明的解决方案也非常简单。

答案 2 :(得分:1)

您想要进行的转换基本上是n(或m的循环转换,具体取决于转变的方向。)

例如,我们有1 2 3 4 5 6 7 a b c(我使用字母和数字来分隔两个数组) 在此转换期间,1将移至4的位置,4将移至77移至c,{{1 {}} {}} {}} {}} {}} {}} {}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} 所以,当时移动一个号码,我们完成了它。

唯一的诀窍是,有时我们会在完成整个转换之前返回c。与案例3一样,这些职位将为3。在这种情况下,我们需要从6开始并重复操作。

您可以注意到我们需要的重复次数是11的最大公约数。

因此,代码看起来像

1 2 a b c d

可以使用well-known recursive formula1 -> a -> c -> 1中轻松计算最大公约数。

修改
它确实有效,我在Java中尝试过。我只将数据类型更改为字符串以便于表示。

2

和欧几里德的公式:

n

答案 3 :(得分:0)

好吧,在这里打字时想一想......

我假设“在记忆中”你不能通过创建一个或多个新阵列作弊,即使是临时的。我还假设你可以有一个临时变量(否则交换内容会变得非常棘手)。

看起来你的两个子阵列可能有不同的大小,所以你不能只用b1和a2与b2等交换a1。

所以你需要弄清楚“a”数组元素首先开始的位置。你通过找到“n”来做到这一点。然后你必须重复保存第一个剩余的“a”元素,并将第一个剩余的“b”元素放在那里。

现在这里变得棘手。你需要将“a”元素保存到它的合法位置,但这可能包含一个未被破坏的元素。最简单的方法可能是将所有剩余的元素向上移动一个,然后将保存的“a”放在最后。如果你反复这样做,你最终会把所有东西放在正确的位置。如果阵列很大,那就很多了。

我相信一个稍微复杂的算法可以只对三角形中的元素进行移位(第一个“q”元素,其中“q”是数组大小之间的差值)并且仅在delta区域中工作时。之后,它只是简单的交换。

答案 4 :(得分:-2)

我们可以使用php中的array_merge

首先使用array_splice()拆分这些数组,然后使用上面的函数。这是为了php。