4. ์›์†Œ ๊ฐœ์ˆ˜ ์„ธ๊ธฐ (Counting Elements) Codility Lesson ํ•œ๊ตญ์–ด ์ •๋ฆฌ๋ณธ (JavaScript ver.)

    ์›์†Œ ๊ฐœ์ˆ˜ ์„ธ๊ธฐ๋ž€?

    ๋ฐฐ์—ด์„ ํ™œ์šฉํ•˜์—ฌ ์ˆซ์ž ์‹œํ€€์Šค๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์—ฐ์†๋œ ์ˆซ์ž aโ‚€, aโ‚, ..., aโ‚™โ‚‹โ‚๋ฅผ ๋ฐฐ์—ด์˜ ์ธ๋ฑ์Šค์— ๋งž์ถฐ ์ €์žฅํ•œ๋‹ค.

    ์˜ˆ๋ฅผ ๋“ค์–ด:

    let A = [4, 2, 4, 5];
    // A[0] = 4, A[1] = 2, A[2] = 4, A[3] = 5
    

    ๊ทธ๋Ÿฌ๋‚˜ ์›์†Œ๋ฅผ ์ง์ ‘ ์ €์žฅํ•˜๋Š” ๋Œ€์‹ , ๊ฐ ์ˆซ์ž์˜ ๋“ฑ์žฅ ํšŸ์ˆ˜๋ฅผ ์„ธ๋Š” ๋ฐฐ์—ด ์„ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๋‹ค.

    ์ด ๊ฒฝ์šฐ, ๋ฐฐ์—ด count[] ๋Š” ํ•ด๋‹น ๊ฐ’์ด ๋“ฑ์žฅํ•œ ํšŸ์ˆ˜๋ฅผ ์ €์žฅํ•œ๋‹ค.

    count[2] = 1; // ์ˆซ์ž 2๋Š” ํ•œ ๋ฒˆ ๋“ฑ์žฅ
    count[4] = 2; // ์ˆซ์ž 4๋Š” ๋‘ ๋ฒˆ ๋“ฑ์žฅ
    count[5] = 1; // ์ˆซ์ž 5๋Š” ํ•œ ๋ฒˆ ๋“ฑ์žฅ
    

    ์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ํŠน์ • ์ˆซ์ž๊ฐ€ ๋“ฑ์žฅํ•œ ํšŸ์ˆ˜๋ฅผ O(1) ์‹œ๊ฐ„์— ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.


    1. O(n + m) ์‹œ๊ฐ„ ๋ณต์žก๋„์˜ ์›์†Œ ๊ฐœ์ˆ˜ ์„ธ๊ธฐ

    ๋‹ค์Œ ํ•จ์ˆ˜๋Š” ๋ฐฐ์—ด A์— ๋“ฑ์žฅํ•˜๋Š” ๊ฐ ์ˆซ์ž์˜ ๊ฐœ์ˆ˜๋ฅผ ์„ธ๋Š” ํ•จ์ˆ˜์ด๋‹ค.

    JavaScript ์ฝ”๋“œ:

    function counting(A, m) {
        let n = A.length;
        let count = new Array(m + 1).fill(0);
        for (let k = 0; k < n; k++) {
            count[A[k]] += 1;
        }
        return count;
    }
    

    ์ด ํ•จ์ˆ˜๋Š” O(n + m) ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ง„๋‹ค. m ๊ฐ’์ด ๋„ˆ๋ฌด ํฌ๋ฉด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.


    2. ๋ฐฐ์—ด ๊ตํ™˜์„ ํ†ตํ•œ ํ•ฉ ์ผ์น˜ ์—ฌ๋ถ€ ํ™•์ธ

    ๋ฐฐ์—ด A์™€ B๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ, ํ•˜๋‚˜์˜ ์›์†Œ๋ฅผ ๊ตํ™˜ํ•˜์—ฌ ๋‘ ๋ฐฐ์—ด์˜ ํ•ฉ์„ ๋™์ผํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฌธ์ œ์ด๋‹ค.

    O(n²) (๋น„ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•)

    function slowSolution(A, B, m) {
        let n = A.length;
        let sumA = A.reduce((a, b) => a + b, 0);
        let sumB = B.reduce((a, b) => a + b, 0);
        
        for (let i = 0; i < n; i++) {
            for (let j = 0; j < n; j++) {
                let change = B[j] - A[i];
                sumA += change;
                sumB -= change;
                
                if (sumA === sumB) return true;
                
                sumA -= change;
                sumB += change;
            }
        }
        return false;
    }
    

    ์ด ๋ฐฉ๋ฒ•์€ ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ์Œ์„ ๊ตํ™˜ํ•ด๋ณด๋ฏ€๋กœ O(n²) ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฐ๋‹ค.


    O(n + m) (ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•)

    ์ข€ ๋” ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•์€ ์›์†Œ ๊ฐœ์ˆ˜๋ฅผ ์„ธ๋Š” ๋ฐฐ์—ด์„ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

    function fastSolution(A, B, m) {
        let n = A.length;
        let sumA = A.reduce((a, b) => a + b, 0);
        let sumB = B.reduce((a, b) => a + b, 0);
        let d = sumB - sumA;
        
        if (d % 2 !== 0) return false;
        d /= 2;
        
        let count = counting(A, m);
        
        for (let i = 0; i < n; i++) {
            if (B[i] - d >= 0 && B[i] - d <= m && count[B[i] - d] > 0) {
                return true;
            }
        }
        return false;
    }
    

    ์ด ๋ฐฉ๋ฒ•์€ O(n + m) ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ง€๋ฉฐ, ๋” ํฐ ์ž…๋ ฅ ๊ฐ’์—๋„ ํšจ๊ณผ์ ์œผ๋กœ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋‹ค.

    ๋ฐ˜์‘ํ˜•

    ๋Œ“๊ธ€