Take every k-th element from the (1 .. n) natural numbers series

前端 未结 4 1033
日久生厌
日久生厌 2020-12-19 06:54

For example, we have series 1, 2, 3, 4, 5. We take every 3 element => 3, 1, 5, 2, 4 (chosen element shouldn\'t remain, we can take while series is not empty). Naive implemen

4条回答
  •  清酒与你
    2020-12-19 07:38

    Here is an implementation with an array representation of the binary tree, only storing the size of the left sub-tree as node value. The input array is not actually stored, but silently assumed to be the leaves at the bottom level, below the binary tree:

    function josephusPermutation(size, step) {
        var len = 1 << 32 - Math.clz32(size-1), // Smallest power of 2 >= size
            tree = Array(len).fill(0), // Create tree in array representation 
            current = 0, 
            skip = step - 1,
            result = Array(size).fill(0),
            goRight, leftSize, order, i, j;
    
        // Initialise tree with sizes of left subtrees as node values
        (function init(i) {
            if (i >= len) return +(i - len < size); // Only count when within size
            var left = tree[i] = init(i*2); // recursive, only store left-size
            return left + (left ? init(i*2+1) : 0); // return sum of left and right 
        })(1);
    
        for (j = 0; j < result.length; j++, size--) {
            current = (current + skip) % size; // keep within range
            order = current;
            for (i = 1; i < len; i = i*2+goRight) {
                leftSize = tree[i];
                goRight = order >= leftSize;
                if (goRight) {
                    order -= leftSize; // Moving rightward, counting what is at left side.
                } else {
                    tree[i]--; // we will remove value at left side
                }
            }
            result[j] = 1 + i - len;
        }
        return result;
    }
    
    var sequence = josephusPermutation(100000, 123456);
    console.log(sequence.join(','));

提交回复
热议问题