Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
Tags
- 문자열
- list
- dfs
- easy
- Array
- sorting
- linked list
- math
- string
- DP
- Binary
- hash table
- 재귀
- Python
- 중간
- backtracking
- binary search
- tree
- 이진트리
- Medium
- 미디움
- leetcode
- 쉬움
- HashTable
- 리트코드
- binary tree
- two pointers
- matrix
- recursive
- Depth-first Search
Archives
- Today
- Total
부부의 코딩 성장 일기
LeetCode 117(Populating Next Right Pointers in Each Node II ) 본문
Algorithm/LeetCode
LeetCode 117(Populating Next Right Pointers in Each Node II )
펩시_콜라 2024. 3. 3. 19:001. 문제 링크
LeetCode - The World's Leading Online Programming Learning Platform
Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.
leetcode.com
2. 문제 설명
- 아래 형태의 binary tree가 주어졌을 때
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
- 각 next pointer를, 해당하는 다음 오른쪽 노드를 가리키도록 채워서 root 반환
- 여기서 다음 오른쪽 노드가 없는 경우, next pointer는 NULL로 설정이 되어야 하며,
- 초기에는 모든 next 포인터가 NULL로 설정이 됨
- 직전 문제인 "Populating Next Right Pointers in Each Node"와의 차이는,
- 직전 문제는 complete binary tree (모든 level의 노드에서 left, right 노드가 채워져있는 트리)였고,
- 해당 문제는 그냥 binary tree라는 점
- 아래 예시 처럼 아래와 같은 binary tree가 주어지면,
- root = [1,2,3,4,5,null,7]
- 반환되는 root는 [1,#,2,3,#,4,5,7,#]이 된다.
- node 1은 next가 존재하지 않으므로 NULL이 되고 (편의상 #로 찍히게 둔 것 같음)
- node 2의 next 는 3, 3의 next는 존재하지 않으므로 NULL
- node 4의 next 는 5, 5의 next는 7, 7의 next는 존재하지 않으므로 NULL이 된다.
3. 처음 풀이
- 이전 문제에서는, cur.next가 존재하면
- cur.right.next = cur.next.left 규칙이 성립이 되서,
- while문으로 코드 작성이 가능했는데,
- 해당 문제에서는 비어있는 node가 존재하기 때문에, 뭔가 복잡하게 느껴졌다.
- 그래서 예전에 풀었던, 전위 순회 식으로 각 node를 list에 쌓아가면서, 이전 node의 next에 현재 node를 연결해주는 식으로 코드를 작성하였다.
- runtime이나, memory가 둘다 90%정도로 나쁘지 않게 나오긴 했는데,
- list를 만들어서, 이전 node 정보를 쌓고 있으니, node의 개수가 많아지면 메모리적으로 비효율적일것 같은 생각이 들었다.
- 그래서 그냥 직전 node의 값만 특정 변수에 저장하는 방식으로 하려 했으나,
- level이 달라진다는 구분자를 아래 코드에서는 list의 element 개수로 잡았어서, 수정이 어려웠다...
"""
# Definition for a Node.
class Node:
def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):
self.val = val
self.left = left
self.right = right
self.next = next
"""
class Solution:
def connect(self, root: 'Node') -> 'Node':
result = []
def helper(root, level):
if not root:
return
if len(result) < level:
result.append([root])
else:
result[level-1][-1].next = root
result[level-1].append(root)
helper(root.left,level+1)
helper(root.right,level+1)
helper(root,1)
return root
4. 다른 풀이
- 여기서는 deque를 사용하면서, tree의 해당 level에서의 개수를 알 수 있게 되고,
- 해당 개수만큼 같은 level안에서 for문을 돌리면서, next 관계를 이어가는 식으로 코드가 작성되어 있다.
- 이전의 값을 저장해두는 prev라는 변수를 두고,
- q에 쌓아둔 node 중 가장 왼쪽 값을 pop하면서,
- 그 값이 left node가 존재할 경우,
- 그 값을 q에 append를 하고,
- 이전의 node의 next에 popped.left를 연결해주고,
- prev는 한칸 next로 이동시킨다.
- 그 값이 right node가 존재할 경우, 마찬가지로
- q에 해당 값을 append하고,
- 이전 node의 next에 popped.right를 연결해주고,
- prev는 next로 이동시킨다.
- 그 값이 left node가 존재할 경우,
class Solution:
def connect(self, root: 'Node') -> 'Node':
if not root:
return None
q = deque()
q.append(root)
dummy=Node(-999) # to initialize with a not null prev
while q:
length=len(q) # find level length
prev=dummy
for _ in range(length): # iterate through all nodes in the same level
popped=q.popleft()
if popped.left:
q.append(popped.left)
prev.next=popped.left
prev=prev.next
if popped.right:
q.append(popped.right)
prev.next=popped.right
prev=prev.next
return root
5. 배운 점
- deque활용
'Algorithm > LeetCode' 카테고리의 다른 글
LeetCode 128(Longest Consecutive Sequence, Python) (2) | 2024.03.07 |
---|---|
LeetCode 283(Move Zeroes, Python) (0) | 2024.03.05 |
LeetCode 268(Missing Number, Python) (1) | 2024.03.01 |
LeetCode 113(Path Sum II, Python) (0) | 2024.02.28 |
LeetCode 107(Binary Tree Level Order Traversal II, Python) (0) | 2024.02.26 |