본문 바로가기
알고리즘/📌백준

[Two Pointer] 용액

by IMSfromSeoul 2021. 12. 23.

📌 문제

📌 문제 풀이

양쪽 끝에서 시작하는 투 포인터를 잡는다.
왼쪽에서 오른쪽으로 가는 것은 증가를 의미,
오른쪽에서 왼쪽으로 가는 것은 감소를 의미한다.

이 때, 왼쪽에서 오른쪽으로 움직이는 증가폭이 0에 더 가깝게 만들어 주는지,
오른쪽에서 왼쪽으로 움직이는 감소폭이 0에 더 가깝게 만들어주는지 알 수 없다.

즉, 증가하는 분과 감소하는 분 중 누가 더 0에 가깝게 만들어주는 지 알 수 없다.

그래서 왼쪽 이동후의 값과 오른쪽 이동후의 값을 비교해서 더 작은 쪽으로 움직인다.

▸ 그림 설명

  • 위의 예에서 현재 arr[left] + arr[right] 의 값은 -8이다.

이 때, 음수의 값이 나왔으니 left 의 값을 증가시켜서 0에 가깝게 만들어야 되지 않을까 생각이 들 수 있다.

그러나, 0에 가깝게 라는 말은 0의 절대값을 의미한다.

위의 경우 음수값인데도 불구하고, right의 값을 감소시키는 것이 0에 더 가깝게 된다.

순회하는 pointer입장에서는 감소하는 값의 폭이 더 클지, 증가하는 값의 폭이 더 클지 모른다.

그래서 미리 arr[left+1]arr[right+1] 의 값을 대조해보고, 더 0에 가까운 쪽으로 pointer가 움직인다.

📌 코드

public class Main {

    static int N;
    static int[] arr;

    public static void main(String[] args) throws FileNotFoundException {

        Scanner sc = new Scanner(System.in);
        N = sc.nextInt();

        arr = new int[N];

        for(int i=0;i<N;i++){
            arr[i] = sc.nextInt();
        }

        int left = 0;
        int right = N-1;
        int min = Integer.MAX_VALUE;

        int leftV=0;
        int rightV=0;

        while(left < right){
            int sum = Math.abs(arr[left] + arr[right]);

            if(min > sum){
                min = sum;
                leftV = left;
                rightV = right;
            }

            int goLeft = Math.abs(arr[left+1]+arr[right]);
            int goRight = Math.abs(arr[left]+arr[right-1]);

            if(goLeft > goRight){
                right--;
            }else{
                left++;
            }
        }
        System.out.print(arr[leftV] + " " + arr[rightV]);
    }
}

'알고리즘 > 📌백준' 카테고리의 다른 글

[Dijkstra] 파티  (0) 2022.01.04
[Two Pointer] 수 들의 합2  (0) 2021.12.22
색종이 만들기  (0) 2021.12.16
백준: 16236번 아기상어  (0) 2021.08.25
백준: 영식이와 친구들  (0) 2021.08.21

댓글