๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ”Ž Algorithm/๐Ÿ“ ๊ฐœ๋… ์ •๋ฆฌ

[๊ฐœ๋… ์ •๋ฆฌ] ํˆฌ ํฌ์ธํ„ฐ

by Seongpyo Hong 2021. 4. 1.

์ตœ๊ทผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ’€๋ฉด์„œ ์‹œ๊ฐ„ ์ดˆ๊ณผ์™€ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋กœ ์ธํ•ด ์ƒ๋‹นํžˆ ์• ๋ฅผ ๋จน์—ˆ๋˜ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค. ํ•ด๋‹น ๋ฌธ์ œ์˜ ๋‹ค๋ฅธ ํ’€์ด๋ฅผ ์ฐพ์•„๋ณด๋‹ˆ ํˆฌ ํฌ์ธํ„ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ†ตํ•ด ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ์•Œ์•˜๊ณ  ์ด์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค. ํˆฌ ํฌ์ธํ„ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ํ•˜๋‚˜์˜ ๋ฐฐ์—ด์—์„œ ๋‘ ๊ฐœ์˜ ์ธ๋ฑ์Šค ํฌ์ธํ„ฐ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์˜๋ฏธํ•œ๋‹ค. ๋ฌธ์ œ๋ฅผ ์˜ˆ์‹œ๋กœ ๋“ค์–ด์„œ ์„ค๋ช…ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

๋ฐฑ์ค€ - 2467. ์šฉ์•ก

์ด ๋ฌธ์ œ์—์„œ 0๊ณผ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๊ฑฐ๋ฆฌ์˜ ํ•ฉ์„ ๊ฐ€์ง€๋Š” ๋‘ ์›์†Œ๋ฅผ ๊ตฌํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋จผ์ € O(N^2)์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋ฅผ ๊ฐ€์ง€๋Š” ๋ฐฉ๋ฒ•์ด ์กด์žฌํ•œ๋‹ค. ํ•˜์ง€๋งŒ ๋ฌธ์ œ์ฒ˜๋Ÿผ N์˜ ํฌ๊ธฐ๊ฐ€ O(N^2)์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ์— ํˆฌ ํฌ์ธํ„ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜๋ฉด O(N)์— ํ•ด๋‹น ๊ฐ’์„ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค. (์ด ๋ฌธ์ œ๋Š” ์ •๋ ฌ์ด ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ „์ฒด ๋ฌธ์ œ์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋Š” O(NlogN)์ด๋‹ค. ํ•˜์ง€๋งŒ ํˆฌํฌ์ธํ„ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋Š” O(N)์ด๋‹ค.)

ํ’€์ด ๋ฐฉ๋ฒ•์€ ๋จผ์ € ์šฉ์•ก์˜ ํŠน์„ฑ๊ฐ’์„ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Left : 0 / Right : N - 1๋กœ ์ดˆ๊ธฐ๊ฐ’์„ ์„ค์ •ํ•œ ํ›„์— ํŠน์„ฑ๊ฐ’์˜ ํ•ฉ์„ ๊ตฌํ•œ๋‹ค. ๋งŒ์•ฝ left์˜ ํŠน์„ฑ๊ฐ’๊ณผ right์˜ ํŠน์„ฑ๊ฐ’์˜ ํ•ฉ์ด 0๋ณด๋‹ค ์ž‘์œผ๋ฉด 0๊ณผ ๊ฐ€๊นŒ์›Œ์ง€๊ธฐ ์œ„ํ•ด์„œ๋Š” left๋ฅผ ๋” ํฐ๊ฐ’์œผ๋กœ ๋ฐ”๊ฟ”์ค˜์•ผ ํ•œ๋‹ค. ๋ฐ˜๋Œ€ ๊ฒฝ์šฐ์—๋Š” right๋ฅผ ๋” ์ž‘์€ ๊ฐ’์œผ๋กœ ๋ฐ”๊ฟ”์ค˜์•ผ ํ•œ๋‹ค. ์ด ๊ณผ์ •์—์„œ 0๊ณผ์˜ ๊ฑฐ๋ฆฌ์˜ ์ตœ์†Œ๊ฐ’์„ ๊ฐฑ์‹ ํ•˜๋ฉด์„œ ์ง„ํ–‰ํ•˜๋ฉด O(N)์— ์ตœ์†Œ๊ฐ’์„ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

Java๋กœ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class Solution2467 {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    public static void main(String[] args) throws IOException {
        int N = Integer.parseInt(br.readLine());
        int[] map = new int[N];
        String[] input = br.readLine().split(" ");
        for (int i = 0; i < N; i++) {
            map[i] = Integer.parseInt(input[i]);
        }
        Arrays.sort(map);
        int left = 0, right = N - 1;
        int min = Integer.MAX_VALUE;
        int[] answer = new int[2];

        while(left < right) {
            int sum = map[right] + map[left];
            if (min > Math.abs(sum)) {
                min = Math.abs(sum);
                answer[0] = map[left];
                answer[1] = map[right];
            }

            if (sum > 0)
                right--;
            else
                left++;
        }

        System.out.println(answer[0] + " " + answer[1]);
    }
}

 

TMI

ํ•ด๋‹น ๋ฌธ์ œ์— ๋Œ€ํ•ด ํˆฌ ํฌ์ธํ„ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ํ’€์ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;

public class Solution2470 {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    public static void main(String[] args) throws IOException {
        ArrayList<Integer> positive = new ArrayList<>();
        ArrayList<Integer> negative = new ArrayList<>();
        int N = Integer.parseInt(br.readLine());

        String[] input = br.readLine().split(" ");
        for (int i = 0; i < N; i++) {
            int cur = Integer.parseInt(input[i]);
            if (cur > 0)
                positive.add(cur);
            else
                negative.add(cur);
        }
        positive.sort(Integer::compareTo);
        negative.sort(Collections.reverseOrder());
        int positiveMin = (positive.size() >= 2) ? Math.abs(positive.get(0) + positive.get(1)) : Integer.MAX_VALUE;
        int negativeMin = (negative.size() >= 2) ? Math.abs(negative.get(0) + negative.get(1)) : Integer.MAX_VALUE;

        int[] result = new int[2];
        int min = Math.min(positiveMin, negativeMin);

        int positiveIdx = 0;
        int negativeIdx = 0;
        int positiveDidx = 0;
        int negativeDidx = 1;
        int curPos = -1000000001, curNeg = 1000000001;
        while (positiveIdx < positive.size() && negativeIdx < negative.size()) {
            curPos = positive.get(positiveIdx);
            curNeg = negative.get(negativeIdx);
            int curMin = Integer.MAX_VALUE;
            int[] temp = new int[2];
            while(positiveIdx < positive.size() && negativeIdx < negative.size()) {
                curPos = positive.get(positiveIdx);
                curNeg = negative.get(negativeIdx);
                if (curMin < Math.abs(curPos + curNeg)) {
                    positiveIdx -= positiveDidx;
                    negativeIdx -= negativeDidx;
                    positiveDidx = (positiveDidx + 1) % 2;
                    negativeDidx = (negativeDidx + 1) % 2;
                    break;
                }
                curMin = Math.abs(curPos + curNeg);
                temp[0] = curNeg;
                temp[1] = curPos;
                positiveIdx += positiveDidx;
                negativeIdx += negativeDidx;
            }

            if (min > curMin) {
                min = curMin;
                result[0] = temp[0];
                result[1] = temp[1];
            }

            positiveIdx += positiveDidx;
            negativeIdx += negativeDidx;
        }


        positiveIdx = (positiveIdx == positive.size()) ? positiveIdx - 1 : positiveIdx;
        negativeIdx = (negativeIdx == negative.size()) ? negativeIdx - 1 : negativeIdx;
        while (!positive.isEmpty() && positiveIdx < positive.size()) {
            curPos = positive.get(positiveIdx++);
            if (min > Math.abs(curPos + curNeg)) {
                min = Math.abs(curPos + curNeg);
                result[0] = curNeg;
                result[1] = curPos;
            }
        }

        while (!negative.isEmpty() && negativeIdx < negative.size()) {
            curNeg = negative.get(negativeIdx++);
            if (min > Math.abs(curPos + curNeg)) {
                min = Math.abs(curPos + curNeg);
                result[0] = curNeg;
                result[1] = curPos;
            }
        }

        if (negativeMin <= positiveMin && negativeMin <= min) {
            System.out.println(negative.get(1) + " " + negative.get(0));
        } else if (positiveMin <= negativeMin && positiveMin <= min) {
                System.out.println(positive.get(0) + " " + positive.get(1));
        } else if (min <= positiveMin && min <= negativeMin) {
            System.out.println(result[0] + " " + result[1]);
        }
    }
}

์ด ๋ฐฉ๋ฒ•์€ ์–‘์ˆ˜ ๋ฐฐ์—ด๊ณผ ์Œ์ˆ˜ ๋ฐฐ์—ด๋กœ ๋‚˜๋ˆ„์–ด์„œ ํŠน์„ฑ๊ฐ’์˜ ํ•ฉ์„ ๊ตฌํ•˜๋Š” ๋ฐฉ์‹์„ ์ง„ํ–‰ํ–ˆ๋‹ค. ์–‘์ˆ˜์™€ ์Œ์ˆ˜๋ฅผ ์ ˆ๋Œ€๊ฐ’์˜ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•œ ํ›„์— ํ•ด๋‹น ์ธ๋ฑ์Šค์—์„œ ํŠน์„ฑ๊ฐ’์˜ ์ ˆ๋Œ€๊ฐ’์„ ๊ณ„์‚ฐํ•˜๋ฉด์„œ ์ตœ์†Œ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐฑ์‹ ํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด ์ธ๋ฑ์Šค ์กฐ์ • ๋ฐ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ์˜ˆ์™ธ ์ผ€์ด์Šค๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์•„ ๋ณต์žกํ•œ ์ฝ”๋“œ๊ฐ€ ๋˜์—ˆ๋‹ค. ๋‹ค๋ฅธ ํˆฌ ํฌ์ธํ„ฐ ๋ฌธ์ œ๋ฅผ ๋งŽ์ด ํ’€์–ด๋ด์•ผ๊ฒ ๋‹ค.

๋Œ“๊ธ€