diff --git a/remove-nth-node-from-end-of-list/radiantchoi.swift b/remove-nth-node-from-end-of-list/radiantchoi.swift new file mode 100644 index 0000000000..2d6f88a63e --- /dev/null +++ b/remove-nth-node-from-end-of-list/radiantchoi.swift @@ -0,0 +1,46 @@ +// Definition for singly-linked list. +public class ListNode { + public var val: Int + public var next: ListNode? + public init() { self.val = 0; self.next = nil; } + public init(_ val: Int) { self.val = val; self.next = nil; } + public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; } +} + +class Solution { + func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? { + // 뒤에서 n번째 노드를 찾기 위한 Two Pointer + var slow = head + var fast = head + var threshold = n + + // fast 포인터를 n만큼 이동시킴 + // 전체 갯수를 c개라고 했을 때, 뒤에서 n번째 노드는 앞에서 c - n + 1번째 노드 + while threshold > 0 { + fast = fast?.next + threshold -= 1 + } + + // padding 노드 생성 + var prev: ListNode? = ListNode() + // slow 포인터에 위치한 노드를 제거하는 전략 - prev 포인터를 slow 포인터의 이전 노드로 이동시킴 + prev?.next = slow + + // 반환을 위한 result 노드 포인터 생성 + let result = prev + + while fast != nil { + prev = prev?.next + slow = slow?.next + fast = fast?.next + } + + // fast 노드는 리스트의 범위를 벗어나 nil이 되었고, + // slow 노드는 뒤에서 n번째 자리에 위치해 있음 + // 그보다 한 칸 앞에 있는 prev 노드의 next를, next?.next로 바꿔 주면, slow 부분의 노드 제거 + prev?.next = prev?.next?.next + + // 반환시 맨 앞의 padding 노드를 제거 + return result?.next + } +} diff --git a/same-tree/radiantchoi.swift b/same-tree/radiantchoi.swift new file mode 100644 index 0000000000..476fc9cdb8 --- /dev/null +++ b/same-tree/radiantchoi.swift @@ -0,0 +1,40 @@ +// Definition for a binary tree node. +public class TreeNode { + public var val: Int + public var left: TreeNode? + public var right: TreeNode? + public init() { self.val = 0; self.left = nil; self.right = nil; } + public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; } + public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) { + self.val = val + self.left = left + self.right = right + } +} + +class Solution { + // 종료조건을 설정하고 재귀로 돌려서 트리 전체를 점검 - DFS + func isSameTree(_ p: TreeNode?, _ q: TreeNode?) -> Bool { + // 둘 다 nil이면 같은 것으로 취급 - TreeNode는 Equatable을 채택하지 않아서, p == q와 같은 직접 비교는 불가능 + if p == nil && q == nil { return true } + // 둘 다 nil인 경우가 아니라면, 한 쪽이라도 nil이면 같은 것이 아니므로 false + guard let p, let q else { return false } + // 값이 같지 않으면 false + guard p.val == q.val else { return false } + + // 둘 다 nil이 아니고, 값이 같음까지 검증한 상태 + if p.isLeafNode && q.isLeafNode { + // 자식이 없다면 true 반환 + return true + } else { + // 자식이 있다면 자식들에 대해 각각 검사 수행 + return isSameTree(p.left, q.left) && isSameTree(p.right, q.right) + } + } +} + +extension TreeNode { + var isLeafNode: Bool { + left == nil && right == nil + } +}