437 https://leetcode.com/problems/path-sum-iii/
1. 노드가 많아봐야 1000개라고 문제에 써있었으니 다른 방법이 기억 안날땐 O(n^2)으로 풀어도 된다.(제출 안하는것보다는 나으니.)
from collections import deque class Solution(object): def pathSum(self, root, sum): if not root: return 0 nodelist = deque([root]) # nodelist에는 모든 노드들을 저장해놓는다. q = deque([root]) while q: p = q.popleft() if p.left: nodelist.append(p.left) q.append(p.left) if p.right: nodelist.append(p.right) q.append(p.right) ret = 0 while nodelist: # 모든 노드들을 돌면서 하나하나 해당되는 합이 있는지 찾는다. n = nodelist.popleft() q = deque([[n, n.val]]) while q: p, temp_sum = q.popleft() if temp_sum == sum: ret += 1 if p.left: q.append([p.left, temp_sum + p.left.val]) if p.right: q.append([p.right, temp_sum + p.right.val]) return ret
2. 근데 O(n^2)은 느리고.. prefix sum으로 O(n)안에 풀수 있다. 내가 알던 일반적인 prefix sum하고 조금 달라서 이해하는데 시간이 걸렸다.
from collections import deque class Solution(object): def pathSum(self, root, target): if not root: return 0 result = 0 cache = {0: 1} stack = deque([[root, 0, cache]]) # 탐색할 노드, 현재까지의 합, 현재까지 방문한 리스트. while stack: # dfs로 돌면서 node, currPathSum, cache = stack.pop() currPathSum += node.val # 현재까지의 합은 계속 누적해준다. oldPathSum = currPathSum - target # oldPathSum은 현재까지의 누적합에서 target을 빼준다. cache에 현재까지 방문한 리스트가 있으므로 만약 이 oldPathSum이 cache에 존재하면 그만큼 더해준다. # 현재까지의 모든 합에서 target을 뺄 경우 그 차액만큼의 값이 만약 이전에 방문했던적이 있으면(cache에 있으면) target을 만들수 있다는 뜻이므로 그만큼을 cache에서 가져와서 더해준다. result += cache.get(oldPathSum, 0) cache[currPathSum] = cache.get(currPathSum, 0) + 1 # cache에는 현재까지 방문했던 경로들을 저장해준다. if node.left: stack.append([node.left, currPathSum, cache.copy()]) if node.right: stack.append([node.right, currPathSum, cache.copy()]) return result
113 https://leetcode.com/problems/path-sum-ii/
from collections import deque class Solution(object): def pathSum(self, root, target): if not root: return [] stack = deque([[root, root.val, [root.val]]]) ret = [] while stack: node, _sum, history = stack.pop() # [현재노드, 현재까지의 합, 현재까지의 노드 히스토리] is_leaf = not node.left and not node.right if _sum == target and is_leaf: # 현재까지의 합과 target이 같고 leaf노드인 경우엔 답이다. ret.append(history) if node.left: stack.append([node.left, _sum + node.left.val, history + [node.left.val]]) if node.right: stack.append([node.right, _sum + node.right.val, history + [node.right.val]]) return ret
82 https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/
class Solution(object): def deleteDuplicates(self, head): dummy = ListNode(0, head) # 더미를 하나 만들어둠. prev = dummy while head and head.next: cur = head next = head.next if cur.val == next.val: # 현재와 다음값이 같을경우 while next and cur.val == next.val: # 다음값이 있으면서 다음값이랑 현재값이랑 다를때까지 계속 전진함. next = next.next prev.next = next # 삭제를 위해 prev.next를 next로 head = next else: prev = head # 현재와 다름값이 다를경우 정상이므로 한칸 이동 head = head.next return dummy.next
83 https://leetcode.com/problems/remove-duplicates-from-sorted-list/
82하고 거의 비슷함.
class Solution(object): def deleteDuplicates(self, head): dummy = ListNode(0, head) while head and head.next: cur = head next = head.next if cur.val == next.val: while next and cur.val == next.val: next = next.next cur.next = next head = next else: head = head.next return dummy.next
'algorithm > problem solving' 카테고리의 다른 글
leetcode 653(2SUM4), 946(stack), 729(이진 탐색), 722(정규식 regex) (0) | 2020.08.02 |
---|---|
leetcode 399(bfs, evalute-division), 406(구현), 304(prefix sum, dp), 303(prefix sum) (0) | 2020.08.01 |
leetcode 116(트리), 117(트리, 레벨 오더), 119(트리), 203(linked list), 849(구현) (0) | 2020.07.19 |
leetcode 1081,316(구현), 1130(트리), 150(후위 표기법 계산), 419(구현, ship) (0) | 2020.07.12 |
leetcode 300(lis, dp), 334(구현), 646(lis, dp) (0) | 2020.07.09 |