๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

์ฝ”๋”ฉํ…Œ์ŠคํŠธ/ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค

[Javascript] ์‹ค์ „ ๋Œ€๋น„ ๋ชจ์˜๊ณ ์‚ฌ 1์ฐจ 2๋ฒˆ

 

ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค
want = ["banana", "apple", "rice", "pork", "pot"]

number = [3,2,2,2,1]

discount = ["chicken", "apple", "apple", "banana", "rice", "apple", "pork", "banana", "pork", "rice", "pot", "banana", "apple", "banana"]

XYZ ๋งˆํŠธ๋Š” ์ผ์ • ๊ธˆ์•ก์„ ์ง€๋ถˆํ•˜๋ฉด 10์ผ๊ฐ„ ํšŒ์› ์ž๊ฒฉ ๋ถ€์—ฌํ•œ๋‹ค.
ํšŒ์›์„ ๋Œ€์ƒ์œผ๋กœ๋Š” ๋งค์ผ ํ•œ๊ฐ€์ง€ ์ œํ’ˆ์„ ํ• ์ธํ•˜๊ณ  ํ• ์ธ ์ œํ’ˆ์€ ํ•˜๋ฃจ์— 1๊ฐœ๋งŒ ๊ตฌ๋งค ๊ฐ€๋Šฅํ•˜๋‹ค.

์ •ํ˜„์ด๋Š” ์›ํ•˜๋Š” ์ œํ’ˆ๊ณผ ์ˆ˜๋Ÿ‰์ด ํ• ์ธํ•˜๋Š” ๋‚ ์งœ์™€ 10์ผ ์—ฐ์†์œผ๋กœ ์ผ์น˜ํ•  ๊ฒฝ์šฐ์— ๋งž์ถฐ ํšŒ์›๊ฐ€์ž…ํ•˜๊ธธ ์›ํ•œ๋‹ค.
๋ผ์ง€๊ณ ๊ธฐ 5๊ฐœ, ๋ฐ”๋‚˜๋‚˜ 5๊ฐœ๋ฅผ ์›ํ•  ๊ฒฝ์šฐ ํ• ์ธ ๋ฒ”์œ„์— ๋ผ์ง€๊ณ ๊ธฐ 5๋ฒˆ, ๋ฐ”๋‚˜๋‚˜ 5๋ฒˆ์ด ํฌํ•จ๋˜์–ด์•ผ ํ•œ๋‹ค.
=> discount = ["pork", "pork", "pork", "pork", "pork", "banana", "banana", "banana", "banana", "banana"] ์ธ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์–ด์•ผ ํ•œ๋‹ค. (์ˆœ์„œ๋Š” ์ƒ๊ด€์—†์Œ)

์ ‘๊ทผ ๋ฐฉ๋ฒ•
sliding window ๋ฐฉ์‹์œผ๋กœ discount์˜ ๋ชจ๋“  ๋ฒ”์œ„๋ฅผ ํƒ์ƒ‰ํ•˜๊ณ  O(N)
๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ answer += 1ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ ‘๊ทผํ•˜์˜€๋‹ค.

๋งŒ์•ฝ 11์ผ์ธ ๊ฒฝ์šฐ 0์ผ์ฐจ๋ฅผ ๋นผ๊ณ  11์ผ์ฐจ๋ฅผ ๋”ํ•˜๊ณ 
12์ผ์ธ ๊ฒฝ์šฐ 1์ผ์ฐจ๋ฅผ ๋นผ๊ณ  12์ผ์ฐจ๋ฅผ ๋”ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰

 ์šฐ์„  ๋ฌผ๊ฑด์„ ๋บ„ ๋‚ ์งœ๋ฅผ ์ €์žฅํ•˜๋Š” prev์™€ ๋ฌผ๊ฑด์„ ๋”ํ•  ๋‚ ์งœ๋ฅผ ์ €์žฅํ•˜๋Š” next ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ ,
์ •ํ˜„์ด๊ฐ€ ์›ํ•˜๋Š” ๋ฌผ๊ฑด๊ณผ ๊ฐœ์ˆ˜๋ฅผ key์™€ value๋กœ ์ €์žฅํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์˜€๋‹ค.
let prev = 0;
let next = 0;

const shoppingObj = {};
want.forEach((e,idx) => shoppingObj[e] = number[idx]);โ€‹


๊ฒฐ๊ณผ๋กœ shoppingObj = {banana: 3, apple: 2, rice: 2, pork: 2, pot: 1}์ด ์ƒ์„ฑ๋˜๊ณ 
์ด shoppingObj์˜ ๋ชจ๋“  value๊ฐ€ 0์ด ๋˜๋ฉด ๋ชจ๋“  ์ œํ’ˆ์„ ํ• ์ธ ๋ฐ›๋Š” ๋‚ ์ด ๋œ๋‹ค.


์ด์ œ discount๋ฅผ ์ˆœํšŒํ•˜๋ฉด์„œ
1. ๋‹ค์Œ๋‚ (next) shoppingObj[key] === discount ์ผ๋•Œ -1; 
2. ์ง€๋‚˜๊ฐ„ ๋‚ (prev) shoppingObj[key] === discount ์ผ๋•Œ +1;
3. shoppingObj[key] !== discount ์ผ๋•Œ ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค.
๋ผ๋Š” ๋กœ์ง์„ ์ง„ํ–‰ํ•œ๋‹ค.


 ์šฐ์„  ์ฒซ 10์ผ๊ฐ„์˜ discount ๊ฐ’์„ shoppingObj์— ๋ฐ˜์˜ํ•œ๋‹ค.

while(next < 10){
    const item = discount[next];
    if(!Object.keys(shoppingObj).includes(item)){
        next++;
    }else{
        shoppingObj[item] -= 1;
        next++;
    }
}



๋‹ค์Œ์œผ๋กœ ์•ž์„œ ์‚ดํ•€ ๋กœ์ง๋Œ€๋กœ next๊ฐ€ discount์˜ ๋งˆ์ง€๋ง‰ ๋‚ ๊นŒ์ง€ ์ง„ํ–‰ํ•œ๋‹ค.

 while(next < discount.length){
    let addItem = discount[next];
    let delItem = discount[prev];

    if(!Object.keys(shoppingObj).includes(addItem)){
        next++;
    }else{
        shoppingObj[addItem] -= 1;
        next++;
    }

    if(!Object.keys(shoppingObj).includes(delItem)){
        prev++;
    }else{
        shoppingObj[delItem] += 1;
        prev++;
    }

    if(allItemSale(shoppingObj)) answer += 1;
}




allItemSale์€ object๋ฅผ ๋ฐ›์•„์™€ object์˜ ๋ชจ๋“  ๊ฐ’์ด 0์ด๋ฉด true๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ ๋ชจ๋“  ๊ฐ’์ด 0์ธ์ง€ ์ฒดํฌํ•œ๋‹ค.

if(allItemSale(shoppingObj)) answer += 1;

const allItemSale = (obj) => {
    let result = Object.values(obj).filter(e => e !== 0);
    return result.length === 0 ? true : false;
}



๊ณ ์น ์ 

1. ๊ตณ์ด discount 10๊นŒ์ง€ ๋”ฐ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ• ๊นŒ?

while(next < 10){
    const item = discount[next];
    if(!Object.keys(shoppingObj).includes(item)){
        next++;
    }else{
        shoppingObj[item] -= 1;
        next++;
    }
}




2. ์ด๋Ÿฐ ํ˜•์‹์˜ ์ฝ”๋“œ๊ฐ€ 3๋ฒˆ์ด๋‚˜ ๋“ฑ์žฅํ•œ๋‹ค. 

if(!Object.keys(shoppingObj).includes(addItem)){
    next++;
}else{
    shoppingObj[addItem] -= 1;
    next++;
}


์ฝ”๋“œ ์ˆ˜์ •

if(next - prev < 10){
    next = setAddItem(shoppingObj, addItem, next);
}else{
    next = setAddItem(shoppingObj, addItem, next);
    prev = setDelItem(shoppingObj, delItem, prev);
}

const setAddItem = (shoppingObj, item, index) => {
    if(Object.keys(shoppingObj).includes(item)){
        shoppingObj[item] -= 1;
    }
    index += 1;
    return index;
}

const setDelItem = (shoppingObj, item, index) => {
    if(Object.keys(shoppingObj).includes(item)){
        shoppingObj[item] += 1;
    }
    index += 1;
    return index;
}


1. if(next > prev)์ผ๋•Œ๋ฅผ ๋ณธ ๋กœ์ง์— ์ถ”๊ฐ€ํ•˜์—ฌ ํ•ด๊ฒฐ

2. ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ์ •๋ฆฌ

ํ•˜๋‚˜์˜ setItem์œผ๋กœ ๋งŒ๋“ค๊ณ  ์‹ถ์—ˆ๋Š”๋ฐ
shoppingObj[item] -= 1;
shoppingObj[item] += 1;
๋‘ ์กฐ๊ฑด์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์–ด๋ ค์›Œ ๋‘๊ฐ€์ง€ ํ•จ์ˆ˜๋กœ ์ž‘์„ฑํ•˜์˜€๋‹ค.

 

function solution(want, number, discount) {
    var answer = 0;
    let prev = 0;
    let next = 0;
    
    const shoppingObj = {};
    want.forEach((e,idx) => shoppingObj[e] = number[idx]);

    while(next - prev < 10){
        const item = discount[next];
        if(!Object.keys(shoppingObj).includes(item)){
            next++;
        }else{
            shoppingObj[item] -= 1;
            next++;
        }
    }

    if(allItemSale(shoppingObj)) answer += 1;

    while(next < discount.length){
        let addItem = discount[next];
        let delItem = discount[prev];

        if(!Object.keys(shoppingObj).includes(addItem)){
            next++;
        }else{
            shoppingObj[addItem] -= 1;
            next++;
        }

        if(!Object.keys(shoppingObj).includes(delItem)){
            prev++;
        }else{
            shoppingObj[delItem] += 1;
            prev++;
        }

        if(allItemSale(shoppingObj)) answer += 1;
    }

    return answer;
}

const allItemSale = (obj) => {
    let result = Object.values(obj).filter(e => e !== 0);
    return result.length === 0 ? true : false;
}
// ๋ฆฌํŒฉํ† ๋ง ์ฝ”๋“œ

function solution(want, number, discount) {
    var answer = 0;
    let prev = 0;
    let next = 0;    
    const shoppingObj = {};
    
    want.forEach((e,idx) => shoppingObj[e] = number[idx]);

    while(next < discount.length){
        let addItem = discount[next];
        let delItem = discount[prev];

        if(next - prev < 10){
            next = setAddItem(shoppingObj, addItem, next);
        }else{
            next = setAddItem(shoppingObj, addItem, next);
            prev = setDelItem(shoppingObj, delItem, prev);
        }

        if(isAllItemSale(shoppingObj)) answer += 1;
    }

    return answer;
}

const setAddItem = (shoppingObj, item, index) => {
    if(Object.keys(shoppingObj).includes(item)){
        shoppingObj[item] -= 1;
    }
    index += 1;
    return index;
}

const setDelItem = (shoppingObj, item, index) => {
    if(Object.keys(shoppingObj).includes(item)){
        shoppingObj[item] += 1;
    }
    index += 1;
    return index;
}
    
const isAllItemSale = (obj) => {
    let result = Object.values(obj).filter(e => e !== 0);
    return result.length === 0 ? true : false;
}