Easy to Understand
IntuitionGet the level first then calculate the swaps each level the return the sum of it.ApproachUsed BFS
as each node I stored in queue q is (TreeNode, level)
# Intuition
Get the level first then calculate the swaps each level the return the sum of it.
<!-- Describe your first thoughts on how to solve this problem. -->

# Approach
Used BFS
as each node I stored in queue `q` is `(TreeNode, level)`
the initialized a dictionary `d` 
Each Iteration I check the value and level
then stored in dictionary `d` like this $$\rightarrow$$ `{level: [Node vals]}`
after sotoring all the values in `d` used a for loop to iterate each level.
During each iteraion used `swap` function to calculate minimum swaps
and added to a vaariable `ans`
return `ans`.
<!-- Describe your approach to solving the problem. -->

# Complexity
- Time complexity: $$O(N\cdot log(n))$$
<!-- Add your time complexity here, e.g. $$O(n)$$ -->

- Space complexity: $$O(n)$$
<!-- Add your space complexity here, e.g. $$O(n)$$ -->

# Code
```python3 []
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def swap(self, arr)->int:
        n = len(arr)
        swap = 0
        arr_pos = list(enumerate(arr))
        arr_pos.sort(key = lambda x:x[1])
        visited = [False]*n

        for i in range(n):
            if visited[i] or arr_pos[i][0] == i:
                continue
            
            cycle_size = 0
            j = i
            
            while not visited[j]:
                visited[j] = True
                j = arr_pos[j][0]
                cycle_size += 1
                
            swap += cycle_size - 1

        return swap
        
    def minimumOperations(self, root: Optional[TreeNode]) -> int:
        if not root : return 0
        if not root.left and not root.right: return 0

        q = deque([(root, 0)])
        ans = 0
        d = {}

        while q:
            curr, level = q.pop()
            if level not in d:
                d[level] = []
            d[level].append(curr.val)
            if curr.left: q.appendleft((curr.left, level+1))
            if curr.right: q.appendleft((curr.right, level+1))

        for level in d:
            ans += self.swap(d[level])
            
        return ans
```
['Tree', 'Breadth-First Search', 'Binary Tree', 'Python3']