๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค/4๋‹จ๊ณ„

[ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค Lv4] : ๊ฐ€์‚ฌ ๊ฒ€์ƒ‰

by Jaeguk 2022. 7. 12.
๋ฌธ์ œ ๋งํฌ

https://school.programmers.co.kr/learn/courses/30/lessons/60060

 

ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค

์ฝ”๋“œ ์ค‘์‹ฌ์˜ ๊ฐœ๋ฐœ์ž ์ฑ„์šฉ. ์Šคํƒ ๊ธฐ๋ฐ˜์˜ ํฌ์ง€์…˜ ๋งค์นญ. ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค์˜ ๊ฐœ๋ฐœ์ž ๋งž์ถคํ˜• ํ”„๋กœํ•„์„ ๋“ฑ๋กํ•˜๊ณ , ๋‚˜์™€ ๊ธฐ์ˆ  ๊ถํ•ฉ์ด ์ž˜ ๋งž๋Š” ๊ธฐ์—…๋“ค์„ ๋งค์นญ ๋ฐ›์œผ์„ธ์š”.

programmers.co.kr

ํ‚ค์›Œ๋“œ๊ฐ€ ๋‹ด๊ธด ๋ฐฐ์—ด์ด ์ฃผ์–ด์กŒ์„ ๋•Œ, ๊ฐ ํ‚ค์›Œ๋“œ ๋ณ„๋กœ ๋งค์น˜๋œ ๋‹จ์–ด๊ฐ€ ๋ช‡ ๊ฐœ์ธ์ง€ ๋ฆฌํ„ดํ•˜์ž.

 

์˜ค๋‹ต

 ๋‚˜๋Š” ๋‹จ์–ด์™€ ํ‚ค์›Œ๋“œ๋ฅผ ์ง์ ‘ ๋น„๊ต๋ฅผ ํ•˜๋Š” ๋ฐฉ์‹์„ ์„ ํƒํ–ˆ๋‹ค.

๋จผ์ œ ๋‹จ์–ด๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ์•ŒํŒŒ๋ฒณ, ๋‹จ์–ด์˜ ๊ธธ์ด๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ถ„๋ฅ˜ํ–ˆ๋‹ค.

๋‹จ์–ด์˜ ๊ธธ์ด์™€ ํ‚ค์›Œ๋“œ์˜ ๊ธธ์ด๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด ๋น„๊ตํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

์ด๋•Œ ํ‚ค์›Œ๋“œ์— ๋ฌผ์Œํ‘œ๊ฐ€ ๋’ค์— ๋ถ™์–ด์žˆ๋‹ค๋ฉด, ๋ฌธ์ž๋ฅผ ์•ž์—์„œ๋ถ€ํ„ฐ ๋น„๊ตํ•˜๊ณ  ๋ฌผ์Œํ‘œ๊ฐ€ ๋‚˜์˜ค๋Š” ์ˆœ๊ฐ„๋ถ€ํ„ฐ๋Š” ๋น„๊ต๋ฅผ ๊ทธ๋งŒํ–ˆ๋‹ค.

๋ฐ˜๋Œ€๋กœ ๋ฌผ์Œํ‘œ๊ฐ€ ์•ž์— ๋ถ™์–ด์žˆ๋‹ค๋ฉด, ๋ฌธ์ž๋ฅผ ๋’ค์—์„œ๋ถ€ํ„ฐ ๋น„๊ตํ•ด์„œ ๋ฌผ์Œํ‘œ๊ฐ€ ๋‚˜์˜ค๊ธฐ ์ „๊นŒ์ง€ ๋น„๊ตํ–ˆ๋‹ค.

์ด๋ ‡๊ฒŒํ•ด์„œ ๋งค์น˜๋˜๋Š” ๋‹จ์–ด์˜ ์ˆ˜๋ฅผ ๋ฆฌํ„ดํ•˜๋„๋ก ํ–ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ์ค‘๋ณต๋œ ํ‚ค์›Œ๋“œ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ์กฐ๊ฑด์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ํ‚ค์›Œ๋“œ๋ณ„๋กœ ์ธ๋ฑ์Šค๋ฅผ ๋ถ€์—ฌํ•ด์„œ ํ‚ค์›Œ๋“œ๋ณ„๋กœ ๋งค์น˜๋œ ๋‹จ์–ด์˜ ๊ฐœ์ˆ˜๋ฅผ ์ €์žฅํ•ด๋‘์—ˆ๋‹ค.

๋งŒ์•ฝ ํ•ด๋‹น ํ‚ค์›Œ๋“œ์˜ ๋งค์น˜๋œ ๋‹จ์–ด์˜ ์ˆ˜๊ฐ€ ์ด๋ฏธ ์ €์žฅ๋˜์–ด์žˆ์œผ๋ฉด ๊ทธ ๊ฐ’์„ ๊บผ๋‚ด์„œ ๋ฆฌํ„ดํ•˜๋„๋ก ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค.

 

์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๊ฐ€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

์˜ค๋‹ต ์ฝ”๋“œ
 
#include <bits/stdc++.h>
using namespace std;
map<stringint> Index;
int Count[100000 + 5];
vector<string> start_with[26][100000 + 1];
vector<string> end_with[26][100000 + 1];
 
int Find(vector<string> words, string str){
    if(Count[Index[str]] != -1//์ด๋ฏธ ํ–ˆ๋˜ ํ‚ค์›Œ๋“œ๋ผ๋ฉด
        return Count[Index[str]];
    
    if(str[0== '?' && str[str.length() - 1== '?')
        return words.size();
    
    if(str[0== '?'){
        //๋’ค์—์„œ๋ถ€ํ„ฐ ๋น„๊ต
        int cnt = 0;
        for(auto Cmp : end_with[str[str.length() - 1- 'a'][str.length()]){
            bool chk = true;
            for(int i = str.length() - 1; i > 0; i--){
                if(str[i] == '?')
                    break;
                if(str[i] != Cmp[i]){
                    chk = false;
                    break;
                }
            }
            if(chk)
                cnt++;
        }
        Count[Index[str]] = cnt;
        return cnt;
    }
    else{
        //์•ž์—์„œ๋ถ€ํ„ฐ ๋น„๊ต
        int cnt = 0;
        for(auto Cmp : start_with[str[0]- 'a'][str.length()]){
            bool chk = true;
            for(int i = 0; i<str.length(); i++){
                if(str[i] == '?')
                    break;
                if(str[i] != Cmp[i]){
                    chk = false;
                    break;
                }
            }
            if(chk)
                cnt++;
            else{
                if(cnt)
                    break;
            }
        }
        Count[Index[str]] = cnt;
        return cnt;
    }
}
 
vector<int> solution(vector<string> words, vector<string> queries) {
    vector<int> answer;
    memset(Count, -1sizeof(Count));
    sort(words.begin(), words.end());
    
    for(auto str : words){
        start_with[str[0- 'a'][str.length()].push_back(str);
        end_with[str[str.length() - 1- 'a'][str.length()].push_back(str);
    }
    
    int idx = 0;
    for(auto str : queries){
        if(Index.find(str) == Index.end()){
            Index.insert({str, idx++});
        }
    }
    
    for(auto str : queries)
        answer.push_back(Find(words, str));
    
    return answer;
}
cs

 

๋ชจ๋“  ๋‹จ์–ด๋ฅผ ์ง์ ‘ ๋น„๊ตํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹จ์–ด์˜ ์–‘์ด ๋งŽ์•„์งˆ์ˆ˜๋ก, ๋‹จ์–ด์˜ ๊ธธ์ด๊ฐ€ ๊ธธ์–ด์งˆ์ˆ˜๋ก ์‹œ๊ฐ„์ด ์˜ค๋ž˜๊ฑธ๋ฆฐ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.

๊ทธ๋ž˜์„œ ํšจ์œจ์„ฑํ…Œ์ŠคํŠธ 1,2,3์—์„œ ์‹œ๊ฐ„์ดˆ๊ณผ๋ฅผ ๋ฐ›์•˜๋‹ค.

 

 ํ’€์ด

์กฐ๊ธˆ ๋” ํšจ์œจ์ ์œผ๋กœ ๋น„๊ตํ•  ํ•„์š”๊ฐ€ ์žˆ์—ˆ๋‹ค.

์ด๋ถ„ํƒ์ƒ‰์„ ์ด์šฉํ•ด๋ฉด ๋œ๋‹ค๊ณ  ํ•˜๋Š”๋ฐ, ๋ฌธ์ž์—ด์—์„œ ์ด๋ถ„ํƒ์ƒ‰์„ ์–ด๋–ป๊ฒŒ ์ด์šฉํ•˜๋Š”์ง€ ๋„์ €ํžˆ ๊ฐ์ด ์žกํžˆ์ง€ ์•Š์•„์„œ ์˜ค๋Š˜๋„ ๊ณ ์ˆ˜๋ถ„๋“ค์˜ ์•„์ด๋””์–ด๋ฅผ ์ฐธ๊ณ ํ–ˆ๋‹ค.

 

์˜ค๋Š˜๋„ "๊ณต๋ถ€ํ•˜๋Š” ์‹๋นต๋ง˜" ๋‹˜์˜ ํ•ด์„ค์„ ์ฐธ๊ณ ํ–ˆ๋‹ค.

 

์ด๋ถ„ํƒ์ƒ‰์„ ์ง์ ‘์ ์œผ๋กœ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, upper_bound์™€ lower_bound๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด์—ˆ๋‹ค. ์•„์ด๋””์–ด๊ฐ€ ์ •๋ง ์ฐธ์‹ ํ•œ ๊ฒƒ ๊ฐ™๋‹ค.

 

๋งŒ์•ฝ ํ‚ค์›Œ๋“œ๊ฐ€ "fro??" ๋ผ๋ฉด "frost", "frodo", "froze" ๋“ฑ๋“ฑ "fro"๋กœ ์‹œ์ž‘ํ•˜๋Š” 5๊ธ€์ž ๋‹จ์–ด๋ฉด ๋ชจ๋‘ ๋งค์น˜๊ฐ€ ๋œ๋‹ค.

์‚ฌ์ „์ˆœ์œผ๋กœ ํ–ˆ์„ ๋•Œ, "fro"๋กœ ์‹œ์ž‘ํ•˜๋Š” 5๊ธ€์ž ๋‹จ์–ด์ค‘์— ๊ฐ€์žฅ ์ฒซ๋ฒˆ์งธ ๋‹จ์–ด๋Š” "froaa"๊ฐ€ ๋  ๊ฒƒ์ด๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰ ๋‹จ์–ด๋Š” "frozz"๊ฐ€ ๋  ๊ฒƒ์ด๋‹ค.

์šฐ๋ฆฌ๋Š” "froaa"์™€ "frozz" ์‚ฌ์ด์— ์žˆ๋Š” ๋‹จ์–ด์˜ ๊ฐœ์ˆ˜๋ฅผ ์ฐพ์•„์ฃผ๋ฉด ๋œ๋‹ค.

 

์ƒํ•œ์„ ์€ upper_bound๋ฅผ ์ด์šฉํ•ด์„œ "frozz"๋ณด๋‹ค ํฐ ๋ฌธ์ž์˜ ์ธ๋ฑ์Šค๋กœ ์„ค์ •ํ•œ๋‹ค.

ํ•˜ํ•œ์„ ์€ lower_bound๋ฅผ ์ด์šฉํ•ด์„œ ์ฒ˜์Œ์œผ๋กœ "froaa"๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์€ ๋ฌธ์ž์˜ ์ธ๋ฑ์Šค๋กœ ์„ค์ •ํ•œ๋‹ค.

์ƒํ•œ์„ ๊ณผ ํ•˜ํ•œ์„  ์‚ฌ์ด์— ์žˆ๋Š” ๋ฌธ์ž๋“ค์ด "fro??"๋กœ ๊ฒ€์ƒ‰๊ฐ€๋Šฅํ•œ ๋‹จ์–ด๋“ค์ด๋‹ค.

 

ํ‚ค์›Œ๋“œ๊ฐ€ "????o" ์ฒ˜๋Ÿผ ๋ฌผ์Œํ‘œ๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ๋ง์ด ๋‹ฌ๋ผ์ง„๋‹ค.

์•ž์˜ ์˜ˆ์‹œ์ฒ˜๋Ÿผ "aaaao"์™€ "zzzzo" ์‚ฌ์ด์— ์žˆ๋Š” ๋‹จ์–ด๋“ค์ด๋ผ๊ณ  ํ•˜๋ฉด

์กฐ๊ฑด์— ๋งž์ง€์•Š๋Š” "froze"์™€ ๊ฐ™์€ ๋‹จ์–ด๋„ ํฌํ•จ์ด ๋œ๋‹ค.

์ด ๊ฒฝ์šฐ์—๋Š” ๋ชจ๋“  ๋‹จ์–ด์™€ ํ‚ค์›Œ๋“œ๋ฅผ ๋’ค์ง‘์–ด์„œ ์•ž์„  ์˜ˆ์‹œ์™€ ๋˜‘๊ฐ™์ด ๋˜๋„๋ก ํ•œ๋‹ค.

  "o????"๋กœ ๋’ค์ง‘๊ณ  ๋‹จ์–ด๋„ "kakao" -> "oakak", "frodo" -> "odorf" ๋กœ ๋’ค์ง‘์œผ๋ฉด

upper_bound, lower_bound๋ฅผ ์ด์šฉํ•ด์„œ ์ƒํ•œ์„  ํ•˜ํ•œ์„ ์„ ์žก์„ ์ˆ˜ ์žˆ๋‹ค.

์ด๋•Œ ๋‹จ์–ด๋ฅผ ๋’ค์ง‘๋Š” ๊ฒƒ์€ reverseํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค.

์ด๋ฒˆ ๋ฌธ์ œ๋ฅผ ํ†ตํ•ด์„œ reverse๋ผ๋Š” ํ•จ์ˆ˜๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์ฒ˜์Œ ์•Œ๊ฒŒ๋˜์—ˆ๋‹ค.

 

์ฝ”๋“œ ์ž‘์„ฑ
 
#include <bits/stdc++.h>
using namespace std;
 
bool cmp(const string& a, const string& b){
    if(a.length() < b.length())
        return true;
    else if(a.length() == b.length()){
        if(a < b)
            return true;
    }
    return false;
}
 
vector<int> Find(vector<string> words, vector<string> reversed, vector<string> queries){
    vector<int> ans;
    for(auto key_word : queries){
        if(key_word[0== '?'){ //๋งจ ์•ž์— ๋ฌผ์Œํ‘œ
            reverse(key_word.begin(), key_word.end());
            string from = "";
            string to = "";
            for(int i = 0; i<key_word.length(); i++){
                if(key_word[i] == '?'){
                    from += "a";
                    to += "z";
                }
                else{
                    from += key_word[i];
                    to += key_word[i];
                }
            }
            ans.push_back(upper_bound(reversed.begin(), reversed.end(), to, cmp)
                - lower_bound(reversed.begin(), reversed.end(), from, cmp));
        }
        else if(key_word[key_word.length() - 1== '?'){
            string from = "";
            string to = "";
            for(int i = 0; i<key_word.length(); i++){
                if(key_word[i] == '?'){
                    from += "a";
                    to += "z";
                }
                else{
                    from += key_word[i];
                    to += key_word[i];
                }
            }
            ans.push_back(upper_bound(words.begin(), words.end(), to, cmp)
                - lower_bound(words.begin(), words.end(), from, cmp));
        }
    }
    return ans;
}
 
vector<int> solution(vector<string> words, vector<string> queries) {
    vector<int> answer;
    vector<string> reversed(words);
    
    for(int i = 0; i<reversed.size(); i++)
        reverse(reversed[i].begin(), reversed[i].end());
    
    sort(words.begin(), words.end(), cmp);
    sort(reversed.begin(), reversed.end(), cmp);
    
    answer = Find(words, reversed, queries);
    return answer;
}
cs

 

๋‹จ์ˆœํžˆ sortํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๊ฒŒ๋˜๋ฉด ์‚ฌ์ „์ˆœ์œผ๋กœ๋งŒ ์ •๋ ฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ž์—ด์˜ ๊ธธ์ด์— ์ƒ๊ด€์—†์ด ์‚ฌ์ „์ˆœ์œผ๋กœ ์ •๋ ฌ์ด ๋œ๋‹ค.

๋น„๊ตํ•จ์ˆ˜๋ฅผ ๋”ฐ๋กœ ์„ ์–ธ ํ•ด์ฃผ์–ด์„œ ๋ฌธ์ž์—ด์˜ ๊ธธ์ด๊ฐ€ ๊ธด ๋ฌธ์ž์—ด์ด ๋ฐ˜๋“œ์‹œ ๋’ค๋กœ ๊ฐ€๋„๋ก ํ•ด์ค€๋‹ค.

 

upper_bound์™€ lower_bound๋ฅผ ์ด๋Ÿฐ์‹์œผ๋กœ๋„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ํ•œ ์ˆ˜ ๋ฐฐ์› ๋‹ค.

๋ฌผ์Œํ‘œ๋ฅผ a์™€ z๋กœ ์ „ํ™˜ํ•˜๋Š” ์•„์ด๋””์–ด๋Š” ๋„ˆ๋ฌด ๊ธฐ๋ฐœํ•˜๋‹ค.

728x90