765. Couples Holding Hands
Brief Description
II – N couples problem
The N couples problem can be solved using exactly the same idea as the N integers problem, except now we have different placement requirements: instead of i == row[i], we require i == ptn[pos[ptn[row[i]]]], where we have defined two additional arrays ptn and pos:
ptn[i] denotes the partner of label i (i can be either a seat or a person) - - ptn[i] = i + 1 if i is even; ptn[i] = i - 1 if i is odd.
pos[i] denotes the index of the person with label i in the row array - - row[pos[i]] == i.
The meaning of i == ptn[pos[ptn[row[i]]]] is as follows:
The person sitting at seat i has a label row[i], and we want to place him/her next to his/her partner.
So we first find the label of his/her partner, which is given by ptn[row[i]].
We then find the seat of his/her partner, which is given by pos[ptn[row[i]]].
Lastly we find the seat next to his/her partner’s seat, which is given by ptn[pos[ptn[row[i]]]].
Therefore, for each pivot index i, its expected index j is given by ptn[pos[ptn[row[i]]]]. As long as i != j, we swap the two elements at index i and j, and continue until the placement requirement is satisfied. A minor complication here is that for each swapping operation, we need to swap both the row and pos arrays.
Here is a list of solutions for Java and C++. Both run at O(N) time with O(N) space. Note that there are several optimizations we can do, just to name a few:
The ptn array can be replaced with a simple function that takes an index i and returns i + 1 or i - 1 depending on whether i is even or odd.
We can check every other seat instead of all seats. This is because we are matching each person to his/her partners, so technically speaking there are always half of the people sitting at the right seats.
There is an alternative way for building the index groups which goes in backward direction, that is instead of building the cycle like i0 --> i1 --> … --> jk --> i0, we can also build it like i0 <-- i1 <-- … <-- ik <-- i0, where i <-- j means the element at index j is expected to appear at index i. In this case, the pivot index will be changing along the cycle as the swapping operations are applied. The benefit is that we only need to do swapping on the row array.
Translation(by Google)
在N夫妇问题可以使用完全相同的理念为来解决N整数的问题,除了现在我们有不同的安装要求:不是的i == row[i],我们要求i == ptn[pos[ptn[row[i]]]],我们定义了两个额外的阵列ptn和pos:
ptn[i]表示标签的合作伙伴i(i可以是座位或人) - - ptn[i] = i + 1如果i是偶数; ptn[i] = i - 1如果i是奇怪的。
pos[i]表示具有标签的人的索引i中row阵列- - row[pos[i]] == i。
含义i == ptn[pos[ptn[row[i]]]]如下:
坐在座位上的人i有一个标签row[i],我们希望将他/她放在他/她的伴侣旁边。
所以我们首先找到他/她的伴侣的标签,由他们给出ptn[row[i]]。
然后我们找到他/她的伴侣的座位,由他们给出pos[ptn[row[i]]]。
最后,我们找到了他/她的伴侣座位旁边的座位,由座位给出ptn[pos[ptn[row[i]]]]。
因此,对于每个支点索引i,其预期指数j由下式给出ptn[pos[ptn[row[i]]]]。只要i != j我们交换两个元素在索引i和j,并一直持续到安置的要求得到满足。这里的一个小问题是,对于每次交换操作,我们需要交换row和pos数组。
以下是Java和C ++的解决方案列表。无论是在运行O(N)的时间与O(N)空间。请注意,我们可以进行多项优化,仅举几例:
所述ptn阵列可以用简单的函数,它的索引被替换i,并返回i + 1或i - 1根据是否i是偶数还是奇数。
我们可以检查每个其他座位而不是所有座位。这是因为我们将每个人与他/她的伴侣相匹配,所以从技术上讲,总有一半人坐在合适的座位上。
有一种替代方法可以构建向后方向的索引组,而不是构建循环,就像i0 --> i1 --> … --> jk --> i0我们也可以构建它一样i0 <-- i1 <-- … <-- ik <-- i0,这i <-- j意味着索引处的元素j应该出现在索引处i。在这种情况下,当应用交换操作时,枢轴索引将沿循环变化。好处是我们只需要交换row数组。
c++ Solution
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片
.
int minSwapsCouples(vector<int>& row) {
int res = 0, N = row.size();
vector<int> ptn(N, 0);
vector<int> pos(N, 0);
for (int i = 0; i < N; i++) {
ptn[i] = (i % 2 == 0 ? i + 1 : i - 1);
pos[row[i]] = i;
}
for (int i = 0; i < N; i++) {
for (int j = ptn[pos[ptn[row[i]]]]; i != j; j = ptn[pos[ptn[row[i]]]]) {
swap(row[i], row[j]);
swap(pos[row[i]], pos[row[j]]);
res++;
}
}
return res;
}
JAVA Solution
public int minSwapsCouples(int[] row) {
int res = 0, N = row.length;
int[] ptn = new int[N];
int[] pos = new int[N];
for (int i = 0; i < N; i++) {
ptn[i] = (i % 2 == 0 ? i + 1 : i - 1);
pos[row[i]] = i;
}
for (int i = 0; i < N; i++) {
for (int j = ptn[pos[ptn[row[i]]]]; i != j; j = ptn[pos[ptn[row[i]]]]) {
swap(row, i, j);
swap(pos, row[i], row[j]);
res++;
}
}
return res;
}
private void swap(int[] arr, int i, int j) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
Quote and Problem Hyperlinked
quoted from leetcode discussion
original problem leetcode 765. Couples Holding Hands