Path In Zigzag Labelled Binary Tree

medium math binary tree zigzag

Problem

In an infinite binary tree the rows are labelled 1, 2, 3, … from the top. In odd-numbered rows the labels increase left to right, while in even-numbered rows they increase right to left (a zigzag). Given the label of a node, return the labels on the path from the root of the tree to that node.

Inputlabel = 14
Output[1, 3, 4, 14]
Row 4 is reversed, so node 14 sits where a normal tree would have 9; its parent chain mirrors back up to the root.

def path_in_zigzag_tree(label):
    path = []
    level = label.bit_length() - 1
    while label >= 1:
        path.append(label)
        # mirror within the level, then move to the parent
        lo, hi = 1 << level, (1 << (level + 1)) - 1
        label = (lo + hi - label) // 2
        level -= 1
    return path[::-1]
function pathInZigZagTree(label) {
  const path = [];
  let level = 31 - Math.clz32(label);
  while (label >= 1) {
    path.push(label);
    const lo = 1 << level;
    const hi = (1 << (level + 1)) - 1;
    label = Math.floor((lo + hi - label) / 2);
    level -= 1;
  }
  return path.reverse();
}
class Solution {
    public List<Integer> pathInZigZagTree(int label) {
        List<Integer> path = new ArrayList<>();
        int level = 31 - Integer.numberOfLeadingZeros(label);
        while (label >= 1) {
            path.add(label);
            int lo = 1 << level;
            int hi = (1 << (level + 1)) - 1;
            label = (lo + hi - label) / 2;
            level--;
        }
        Collections.reverse(path);
        return path;
    }
}
vector<int> pathInZigZagTree(int label) {
    vector<int> path;
    int level = 31 - __builtin_clz(label);
    while (label >= 1) {
        path.push_back(label);
        int lo = 1 << level;
        int hi = (1 << (level + 1)) - 1;
        label = (lo + hi - label) / 2;
        level--;
    }
    reverse(path.begin(), path.end());
    return path;
}
Time: O(log label) Space: O(log label)