트리 내에 존재하는 엣지 를 타고 가장 합이 높은 부분을 구하는 문제이다. 어제와 유사한 문제라고 생각해서 비슷하게 접근했으나 머리가 대차게 깨져버렸다.

어제 와 유사한 코드로 접근하였으나 - 값의 여부와 한가지 패스 안에서는 길을 타고 다시 거슬러 올라오면 안 된다는 부분에서 신경이 쓰여 preorder를 사용했다. 중복을 처리해줄 방법이 없어 생각보다 애를 많이 먹었다... 

if를 이용해서 틀릴 때마다 처리를 해주었으나. 99개 테스트 케이스에서 56 이 한계였다. preOrder, postOrder 전부 실패했다. prefix를 이용하기 위해 리스트 넘기는 방법, max를 이용해 현재 비교대상을  3번 비교하는 방법 전부 실패했다.

뭔가 잡힐듯 말듯한데 자꾸 실패해서 분하다...

 

약 1시간 정도 풀다가 실패해서 discuss를 보고 오니 내가 구해야 할 명확한 목적을 알고 나니 풀이가 쉬워졌다.

 

머리 깨진 풀이

class Solution {
    int max;
    public int maxPathSum(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        max = Integer.MIN_VALUE;
        helper(root, list);
        int total = list.get(list.size()-1);
        for (int i = 0; i < list.size()-1; i++) {
            max = Math.max(Math.max(total,total-list.get(i)),max);
        }
        return max;
    }

    public void helper(TreeNode node, List<Integer> list){
        if(node == null) return;
        helper(node.left, list);
        int previous = list.size() == 0 ? 0 : list.get(list.size()-1);;
        list.add(previous+node.val);
        max = Math.max(max,node.val);
        helper(node.right,list);
    }
}

트리 순회를 위해 helper를 선언해 중위 순회를 선택했다. 이유는 후위 순회를 하게 된다면 리프부터 타고 올라가야 하는데 이 기준점을 정해주기 가 생각보다 어려웠다. prefix를 사용해야 한다는 압박감 때문 인지. 후위 순회를 하게 되니 오류가 많이 생겼다. 

디스커스에서 읽고 바로 풀이 방법을 바꾼 힌트 를 보자.

우리가 구해야 할 4가지 경우의 수가 있다.

1. 왼쪽 패스 + 현재 값

2. 오른쪽 패스 + 현재 값

3. 왼쪽 패스 + 오른쪽 패스 + 현재 값

4. 현재 값 자체로 위 값보다 큰 경우

이 4 가지를 명확히 하고 갔어야 했는데 이게 안되니 null 이 여러 번 들어간 깊이 있는 트리인 경우 오답이 나게 되는 것이다. ㅠ

 

위 4가지 힌트를 얻어서 작성한 풀이법이다. 

class Solution{
	int max = Integer.MIN_VALUE;
    
	public int maxPathSum(TreeNode root) {
        helper(root);
        return max;
    }
    
    public int helper(TreeNode node){
    	if(node == null) return Integer.MIN_VALUE;
        int left = helper(node.left);
        int right = helper(node.right);
        
        max = Math.max(max,Math.max(left,right));
        max = Math.max(max,node.val);
        max = Math.max(max,node.val+Math.max(left,0)+Math.max(right,0));
        return node.val + Math.max(0,Math.max(left,right));
    }
}

max 값을 비교할 Integer를 선언해주고 , 현재 값이 - 값이라면 무조건 0으로 초기화시켜주었다. 

left 패스, right 패스를 각각 구하고 현 max와 패스의 합 +현재 값

그리고 현재 값에 패스 값 중 높은 값을 다음으로 넘겨주는 재귀를 작성하였다. 

 

class Solution{
	int value = Integer.MIN_VALUE;

    public int maxPathSum(TreeNode root) {
        int temp = process(root);
        return Math.max(temp, value);
    }

    public int process(TreeNode head){
        if(head == null){
            return 0;
        }
        int leftTree = Math.max(0, process(head.left));
        int rightTree = Math.max(0, process(head.right));
        value = Math.max(value, leftTree + rightTree + head.val);
        return Math.max(leftTree, rightTree) + head.val;
    }
}

이 사람도 보면 참 깔끔하게 작성한 거 같다. 왼쪽 패스, 오른쪽 패스를 나누고 현재 값의 맥스를 왼쪽 오른쪽의 합과 현재 값을 이용하고 다음 재귀로 왼쪽 오른쪽 중 큰 값을 현재 값에 더해 넘겨준다.

 

maxValue = Math.max(maxValue, left + right + node.val);

작성할 때 난감 했던 부분이다. maxVaule를 현재 와 왼쪽 오른쪽 그리고 노드의 값을 합친 값으로 업데이트를 하는 것이 아닌가.

문제의 포인트를 잡지 못해서 이상한 풀이법으로 나가 결국 맞지 못한 문제였다.

'PS > LeetcCode' 카테고리의 다른 글

1월4일 문제 풀기  (2) 2023.01.04
Easy 문제 풀기 Day2(83/618)  (0) 2023.01.03
1339. Maximum Product of Splitted Binary Tree  (0) 2022.12.10
Easy 문제 풀기 Day1(79/610)  (0) 2022.12.03
BFS 문제들을 풀어보자 1탄  (0) 2022.08.25

+ Recent posts