{}
run-icon
main.swift
//Variant of all nodes at k distance /** * Variant: was: you’re given the root node of a binary tree, the value N of a target node, a distance K and a target sum T. Find all sets of nodes at distance K from node N which sum to T. * */ public class TreeNode { public var val: Int public var left: TreeNode? public var right: TreeNode? init(_ val: Int, _ left: TreeNode? = nil, _ right: TreeNode? = nil) { self.val = val self.left = left self.right = right } } extension TreeNode: Hashable { public static func == (lhs: TreeNode, rhs: TreeNode) -> Bool { return lhs === rhs } public func hash(into hasher: inout Hasher) { hasher.combine(ObjectIdentifier(self)) } } class Solution { //we need to look at the tree as a graph instead of tree var graph = [TreeNode: [TreeNode]]() //adj list func distanceKEqualSum(_ root: TreeNode?, _ targetVal: Int, _ k: Int, _ targetSum: Int) -> [[Int]] { guard let root = root, let target = findTarget(root, targetVal) else { return [] } buildGraph(root, nil) var result = [[Int]]() var nodes = [Int]() //nodes at K distance var visited = Set<TreeNode>() visited.insert(target) distanceKHelper(target, 0, k, &visited, &nodes) print(nodes) //we need to perform subset sum in the nodes list to get those nodes that sum to targetSum subsetSumHelper(nodes, 0, targetSum, [], &result) return result } private func findTarget(_ root: TreeNode?, _ targetVal: Int) -> TreeNode? { guard let root = root else { return nil } if root.val == targetVal { return root } return findTarget(root.left, targetVal) ?? findTarget(root.right, targetVal) } private func subsetSumHelper(_ nums: [Int], _ index: Int, _ targetSum: Int, _ path: [Int], _ result: inout [[Int]]) { if targetSum == 0 { result.append(path) return } if targetSum < 0 || index >= nums.count { return } //include element at index subsetSumHelper(nums, index + 1, targetSum - nums[index], path + [nums[index]], &result) //exclude element at index subsetSumHelper(nums, index + 1, targetSum, path, &result) } private func distanceKHelper(_ node: TreeNode, _ distance: Int, _ k: Int, _ visited: inout Set<TreeNode>, _ result: inout [Int]) { if distance == k { result.append(node.val) return } for neighbor in graph[node, default: []] { guard visited.contains(neighbor) == false else { continue } visited.insert(neighbor) distanceKHelper(neighbor, distance + 1, k, &visited, &result) } } private func buildGraph(_ root: TreeNode?, _ parent: TreeNode?) { if let root = root, let parent = parent { graph[root, default: []].append(parent) graph[parent, default: []].append(root) } if let left = root?.left { buildGraph(left, root) } if let right = root?.right { buildGraph(right, root) } } } let root = TreeNode(5, TreeNode(3, TreeNode(1), TreeNode(4) ), TreeNode(8, TreeNode(7), TreeNode(9) ) ) let solution = Solution() let results = solution.distanceKEqualSum(root, 3, 1, 5) print(results) // Output: possible [[1, 9], [4, 6]] etc., depending on tree and target
Output