当前位置 : 主页 > 手机开发 > 无线 >

algorithm – 使用最少的移动对数组进行排序

来源:互联网 收集:自由互联 发布时间:2021-06-10
我遇到过这个问题: there is n+1 loading docks. a permutation of boxes 1-n is placed on the first n. there is a fork that can move one box to an empty location at a time. Give an algorithm to sort the boxes with minimum number of mo
我遇到过这个问题:

there is n+1 loading docks. a permutation of boxes 1->n is placed on
the first n. there is a fork that can move one box to an empty
location at a time. Give an algorithm to sort the boxes with minimum
number of moves
.

我的算法(伪代码)(基于1的索引)

>(0)将计数器设置为0
>(1)遍历查找最大框的数组.将其移至最后一个插槽(n 1).递增计数器1.
>(2)然后从开始重新开始到limit = n_th slot,找到max box并将其交换到结尾.增加计数器3(因为交换需要3次移动).
>(3)将限制减少1
>回到(2)直到极限达到1

更新:Saruva Sahu在下面提出了一个非常好的解决方案,我优化了一点以避免“交换”.

public static void moveToPos(int[] nums) {
        int tempLoc = nums.length - 1;
        final int n = nums.length - 2;
        // boxes --> loc
        Map<Integer, Integer> tracking = new HashMap<>();
        for (int i = 0; i < n; ++i) {
            // if the target place is empty
            if (nums[i] == tempLoc) {
                // then move it there
                nums[tempLoc] = nums[i];
                // new temp loc
                tempLoc = i;

            }
            else if(nums[i] != i) {
                // move current box at target out of the way
                nums[tempLoc] = nums[nums[i]];
                if (tempLoc != nums[nums[i]]){
                    // nums[i] is not at the right place yet
                    // so keep track of it for later
                    tracking.put(nums[nums[i]], tempLoc);
                }
                nums[nums[i]] = nums[i];
                tempLoc = i;
            }
        }

        // move the unstelled to its right place
        while (!tracking.isEmpty()) {
            // where is the box that is supposed to be at tempLoc 
            int loc = tracking.remove(tempLoc);
            nums[tempLoc] = nums[loc];
            // make the emtpy spot the new temp loc
            tempLoc = loc;
        }

    }

对此有什么更好的算法?

有一种非常好的技术可以解决这个问题.让我们说我们有这个顺序的盒子.

[5] 4 2 3 1

用第5个交换第1个方框(这是第1个方框的值)得到:

[1] 4 2 3 5

现在第一个盒子在正确的位置.转到第二个.

1 [4] 2 3 5

用第4个交换第2个方框(这是第2个方框的值)得到:

1 [3] 2 4 5

现在再次检查第二个盒子是否处于正确位置.
交换第二个框与第三个(这是第二个框的值)得到:

1 [2] 3 4 5

现在再次检查第二个盒子是否处于正确位置.如果没有移动到下一个索引.
重复上述步骤直到第n个框.

1 2 [3] 4  5

1 2  3 [4] 5

1 2  3  4 [5]

而已.盒子将被分类.

重要注意事项:

>此算法仅适用于阵列中所有数字都是连续的情况(排序或未排序无关紧要).请求者在评论部分确认了此要求.
>在每次交换期间,您在其正确的最终位置放置至少一个框,这是该算法的最佳选择.在最好的情况下,您可以放置​​2个盒子
在第一次交换中发生的每次交换([5] 4 2 3 1 – > [1] 4 2 3 5).
>每个交换都需要一个空盒子/空间,可根据要求提供.
>每次交换(A和B之间)由3个移动组成.将A移动到空白区域,然后将B移动到A的位置,然后将A移回B的旧位置.因此,A保证获得正确的最终位置.

更新:
Nico建议的算法给出了最小移动次数,如下所示:

5 4 2 3 1  [ ] : Start positions
.. 4 2 3 1 [5] : 1st move
1 4 2 3 .. [5] : 2nd move
1 4 2 3 5  [ ] : 3rd move
1 .. 2 3 5 [4] : 4th move
1 2 .. 3 5 [4] : 5th move
1 2 3 .. 5 [4] : 6th move
1 2 3 4 5  [ ] : 7th move

共计7次移动的代价是时间复杂度较高的O(n ^ 2).

另一方面,我建议的算法保证最低时间复杂度O(n),但不是最小移动次数,如下所示:

[5] 4 2 3 1  -> [1] 4 2 3 5 : 3 moves to swap 5 and 1
1 [4] 2 3 5  -> 1 [3] 2 4 5 : 3 moves to swap 4 and 3
1 [3] 2 4 5  -> 1 [2] 3 4 5 : 3 moves to swap 3 and 2

在O(n)的较低时间复杂度下总共9次移动.

网友评论