https://leetcode.com/problems/binary-tree-level-order-traversal-ii/description/
코드설명
ArrayList + 깊이우선탐색(DFS) + 넓이우선탐색(BFS) 를 활용합니다.
기본적으로 bottom-up level order 로 출력해야 하므로 ArrayList의 add(0, value) 값을 통해 addFirst() 와 같은 형태로 사용합니다. 내가 원하는 위치에 넣을 수 있는 기능이지요.
이를 통해, 순서를 뒤집어서 저장할 수 있고, 기본적으로 새로 삽입하는 값들을 모두 맨 앞에 삽입하도록 하면 bottom-up 방식으로 될 것 입니다.
처음에 패착은, DFS에서 모든 로직을 탄뒤에 반환하면서 처리해야 bottom-up 방식으로 구현하기 훨씬 편하다고 생각했는데, ArrayList의 addFirst() 의 기능을 add(0, 값)의 형태로 사용하면 BFS와 DFS를 거의 같은 방식으로 구현할 수 있습니다.
코드
BFS를 활용한 정답코드2입니다.
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { List<List<Integer>> answer = new ArrayList<>(); public List<List<Integer>> levelOrderBottom(TreeNode root) { if(root == null) return answer; BFS(root); return answer; } void BFS(TreeNode node){ Queue<TreeNode> q = new LinkedList<>(); q.offer(node); while(!q.isEmpty()){ int size = q.size(); List<Integer> level = new ArrayList<>(); for(int i=0; i<size; i++){ TreeNode tempNode = q.poll(); level.add(tempNode.val); if(tempNode.left != null) q.offer(tempNode.left); if(tempNode.right != null) q.offer(tempNode.right); } answer.add(0, level); } } }
DSF를 활용한 정답코드1입니다.
아래의 오류코드를 개선시킨 코드입니다.
핵심은, list의 size가 level보다 작을때, 새로 list에 값을 추가하되 아래 Level부터 출력해야하므로 list.add(0, new ArrayList<>()); 를 통해 맨 앞에 새로운 ArrayList를 추가해줍니다.
bottom-up level order이기에 아래와 같이 list.size() - level -1 로 인덱스를 처리해줍니다. 가장 맨 아래 level이 맨 앞에 오도록 처리하는 것이지요.
list.get(list.size() - level - 1).add(node.val);
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { List<List<Integer>> answer = new ArrayList<>(); public List<List<Integer>> levelOrderBottom(TreeNode root) { if(root == null) return answer; DFS(0, root, answer); return answer; } void DFS(int level, TreeNode node, List<List<Integer>> list){ if(node == null) return; if(list.size() <= level) list.add(0, new ArrayList<>()); DFS(level + 1, node.left, list); DFS(level + 1, node.right, list); list.get(list.size() - level - 1).add(node.val); } }
처음에 잘못 푼 코드입니다.
이 코드의 경우 아래와 같이 입력이 들어왔을때,
[1,2,3,4,null,null,5]
정답은 아래와 같이 나와야합니다만,
[[4, 5], [2, 3], [1]]
제 코드는 같은 레벨임에도 다른 배열에 처리됩니다.
[[4],[5],[2,3],[1]]
원인은, DFS가 분기되면서 서로 각 자식의 노드만 포함하기 때문입니다. 같은 레벨을 모두 고려하는 것이 아니지요.
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { List<List<Integer>> answer = new ArrayList<>(); public List<List<Integer>> levelOrderBottom(TreeNode root) { if(root == null) return answer; DFS(root); List<Integer> arr = new ArrayList<>(); arr.add(root.val); answer.add(arr); return answer; } int DFS(TreeNode node){ List<Integer> arr = new ArrayList<>(); if(node.left != null){ arr.add(DFS(node.left)); } if(node.right != null){ arr.add(DFS(node.right)); } if(arr.size() > 0) answer.add(arr); return node.val; } }