Algorithm to apply permutation in constant memory space

后端 未结 8 1576
温柔的废话
温柔的废话 2020-12-13 21:29

I saw this question is a programming interview book, here I\'m simplifying the question.

Assume you have an array A of length n, and you ha

8条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-13 21:49

    @RinRisson has given the only completely correct answer so far! Every other answer has been something that required extra storage — O(n) stack space, or assuming that the permutation P was conveniently stored adjacent to O(n) unused-but-mutable sign bits, or whatever.

    Here's RinRisson's correct answer written out in C++. This passes every test I have thrown at it, including an exhaustive test of every possible permutation of length 0 through 11.

    Notice that you don't even need the permutation to be materialized; we can treat it as a completely black-box function OldIndex -> NewIndex:

    template
    void permute(RandomIt first, RandomIt last, const F& p)
    {
        using IndexType = std::decay_t;
    
        IndexType n = last - first;
        for (IndexType i = 0; i + 1 < n; ++i) {
            IndexType ind = p(i);
            while (ind < i) {
                ind = p(ind);
            }
            using std::swap;
            swap(*(first + i), *(first + ind));
        }
    }
    

    Or slap a more STL-ish interface on top:

    template
    void permute(RandomIt first, RandomIt last, ForwardIt pfirst, ForwardIt plast)
    {
        assert(std::distance(first, last) == std::distance(pfirst, plast));
        permute(first, last, [&](auto i) { return *std::next(pfirst, i); });
    }
    

提交回复
热议问题