The code works as recursion.

```
If the root value in the range [L, R]
we need return the root, but trim its left and right subtree;
else if the root value < L
because of binary search tree property, the root and the left subtree are not in range;
we need return trimmed right subtree.
else
similarly we need return trimmed left subtree.
```

Without freeing memory

```
class Solution {
public:
TreeNode* trimBST(TreeNode* root, int L, int R) {
if (root == NULL) return NULL;
if (root->val < L) return trimBST(root->right, L, R);
if (root->val > R) return trimBST(root->left, L, R);
root->left = trimBST(root->left, L, R);
root->right = trimBST(root->right, L, R);
return root;
}
};
```

Free the memory

As @StefanPochmann pointed out, it works well to delete only non-root nodes of the whole tree. His solution is as below. Thanks.

```
TreeNode* trimBST(TreeNode* root, int L, int R, bool top=true) {
if (!root)
return root;
root->left = trimBST(root->left, L, R, false);
root->right = trimBST(root->right, L, R, false);
if (root->val >= L && root->val <= R)
return root;
auto result = root->val < L ? root->right : root->left;
if (!top)
delete root;
return result;
}
```