programmers : https://programmers.co.kr/learn/courses/30/parts/12077

 

programmers 해시 level2 전화번호목록 문제입니다.

 

전체스트링 하나가 다른 스트링의 접두사가 되는 부분이 있는지 확인하는 문제입니다.

 

******

사실 이 문제는 .. 테스트케이스가 좀 부족한 문제이지 않나 싶습니다.

O(N^2) 코드가 O(N+NlogN) 코드보다 빠르게 정말 더빠르게 해결됨을 확인했습니다.

아마 N^2 의 완탐코드에서 정답이 빨리 찾아지는 테스트케이스만 모여있기 때문이 아닐까 추측해봅니다

******

 

예를 들어 

12 13 124 2 52 라는 값이 있으면

12 가 124의 접두사가 되기 때문에 정답이 false 가 됩니다.

 

이 문제는 범위가 100만 이기 때문에 사실 N^2 의 복잡도로는 문제가 해결되지 않을줄 알았습니다.

다음은 O(N^2) 코드입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <string>
#include <vector>
 
using namespace std;
 
bool solution(vector<string> phone_book) {
    bool answer = true;
    
    for(int i = 0; i<phone_book.size()-1; i++){
        for(int j = 0; j<phone_book.size(); j++){
            if(phone_book[i].size()>phone_book[j].size() || i==j) continue;
            bool temp = true;
            for(int k = 0; k<phone_book[i].size(); k++){
                if(phone_book[i][k] != phone_book[j][k]){
                    temp = false;
                    break;
                }
            }
            if(temp){
                answer = false;
                break;
            }
        }
        if(!answer) break;
    }
    
    return answer;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

그런데 빠른시간내로 통과되더라구요? ??.. 

하지만 문제를 이런식으로 풀게 되면 분명 TLE를 받게될 경우들이 많아질 것이 분명합니다..

 

접두사를 좀더 빠르게 찾는 방법이 무엇일까요?

답은 정렬입니다.

위의 12 13 124 2 3 을 정렬하면

12 124 13 2 3 이라는 사전순서의 정렬이 됩니다.

 

그리고 O(N)으로 문제를 해결하면 됩니다.

접두사가 있는지 없는지는 현재위치와 다음위치만 비교해주면 되기 때문입니다.

다음은 정렬을 이용한 O(N)+O(NlogN) 코드입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
 
bool solution(vector<string> phone_book) {
    bool answer = true;
 
    sort(phone_book.begin(), phone_book.end());
 
    for (int i = 0; i < phone_book.size() - 1; i++)
    {
        if (phone_book[i] == phone_book[i + 1].substr(0, phone_book[i].size()))
        {
            answer = false;
            break;
        }
    }
 
    return answer;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

'algorithm > programmers' 카테고리의 다른 글

Programmers 라면공장(C++)  (0) 2020.07.02
programmers N으로 표현  (0) 2020.03.12
programmers H-Index C++  (0) 2020.03.10
programmers 가장 큰 수  (0) 2020.03.10
programmers K번째수  (0) 2020.03.10

programmers : https://programmers.co.kr/learn/courses/30/parts/12198

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

H-Index는 과학자의 생산성과 영향력을 나타내는 지표입니다. 어느 과학자의 H-Index를 나타내는 값인 h를 구하려고 합니다. 위키백과1에 따르면, H-Index는 다음과 같이 구합니다.

어떤 과학자가 발표한 논문 n편 중, h번 이상 인용된 논문이 h편 이상이고 나머지 논문이 h번 이하 인용되었다면 h의 최댓값이 이 과학자의 H-Index입니다.

어떤 과학자가 발표한 논문의 인용 횟수를 담은 배열 citations가 매개변수로 주어질 때, 이 과학자의 H-Index를 return 하도록 solution 함수를 작성해주세요.

 

programmers 정렬 level2 H-Index 문제입니다.

 

문제를 이해못하셨을 수도 있으니 간단히 설명하면 다음과 같습니다

 

예제에 있는 3 0 6 1 5 의 경우 3, 5, 6은 3이라는 값보다 모두 '이상' 이고 0, 1은 3이라는 값보다 모두 '이하' 입니다

테스트케이스를 하나 더 만들어보겠습니다.

3 5 7 7 7 7 7 7 의 테스트케이스의 경우 답은 무엇일까요? ==> 6이 됩니다.

7 7 7 7 7 7 이 6개의 수는 모두 6이상이고, 3, 5는 6이하 이기 때문이죠

 

접근법은 결국 정렬을 하신 후에, 이분탐색을 이용하는 것입니다.

 

초기 answer답을 0, 탐색 인덱스 idx를 0으로 설정해보겠습니다.

 

처음에 3을 만났네요? size - idx = 8이므로 answer는 당연히 3으로 초기화됩니다.

5를 만났습니다. size - idx = 7 이므로 answer는 5로 초기화 됩니다.

7을 만났습니다. size - idx = 6 이므로 7이라는 값은 정답이 될 수 없겠습니다.

현재 answer : 5, 탐색중인 수 : 7

이 2개의 수로 이분탐색을 해보면

(5+7)/2 = 6일때 size - idx = 6 을 만족하게 되네요!

그래서 정답이 6이 되는 것이고, 6보다 큰 H-Index를 찾을 수 없을테니 탐색을 종료해주시면 되는겁니다.

 

코드는 다음과 같습니다~

#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int solution(vector<int> citations) {
    int answer = 0;

    sort(citations.begin(), citations.end());

    // h번 이상 인용된 논문이 h개이고
    // 나머지 논문들은 h개 이하로 인용되었다

    // 3 5 7 9 10 -> answer : 4
    // 3 5 7 7 7 7 7 7 -> answer : 6 
    for (int i = 0; i < citations.size(); i++) {
        int temp = citations[i];
        if (citations.size() - i >= temp) answer = max(answer, temp);
        else {
            // temp보다는 작지만 answer 보다는 커질수 있음을 의미함
            // 이분탐색으로 answer와 temp 사이의 적합한 수를 찾음
            int s = answer;
            int e = temp;
            int m;
            while (s < e) {
                m = (s + e) / 2;
                if (citations.size() - i > m) s = m + 1;
                else if (citations.size() - i == m) {
                    s = m;
                    break;
                }
                else e = m;
            }
            answer = max(answer, s);
            break;
        }
    }

    return answer;
}

 

 

'algorithm > programmers' 카테고리의 다른 글

programmers N으로 표현  (0) 2020.03.12
programmers 전화번호 목록  (0) 2020.03.10
programmers 가장 큰 수  (0) 2020.03.10
programmers K번째수  (0) 2020.03.10
programmers 여행경로  (0) 2020.03.10

programmers : https://programmers.co.kr/learn/challenges?selected_part_id=12198

 

programmers 정렬 level2 가장 큰 수 문제입니다.

 

문제를 푸는 방법은 2가지가 있습니다. (+힌트 는 맨마지막에.. )

 

핵심은 수를 대체 어떤식으로 비교하냐 인데

예제의 6 2 10은 이해하셨겠지만 6210이 최대의 수가 됩니다.

예제에서 큰 힌트를 주었습니다. 3 과 30 입니다.

3, 30 => 330, 303 둘 중에서는 330이 더 크게되니 3이 30보다 크게끔 만들어야 한다는 뜻입니다.

 

애초에 범위는 10만이기 때문에 n^2로 해결할 수 없습니다. 즉 브루트포스가 불가능하단 소립니다.

 

방법1 : 수를 직접 범위내의 자릿수까지 만들어주는 방법

문제에서 수는 4자리 이하로만 주어진다고 했습니다. 이건 정말 큰 힌트가 됩니다.

모든 수를 4자리 이하로 만들어버리면 대수비교가 가능해집니다.

예제를 보면 6000, 2000, 1000 이렇게 만들 수 있는 것입니다.

결국 그대로 정렬되게 되고, 6,2,10만 따오면 되는 것입니다.

 

그럼 3과 30은 어떻게 비교할까요?

3000, 3000이 되기때문에 무작정 *10 을 해서는 안된다는 뜻이 됩니다.

그렇다고 무작정 뒤에 임의의 숫자를 집어넣는다 생각할 수 있는데 

3999, 3099 는 좋은 비교대상이 되겠지만, 3, 34도 임의의 숫자 9? 로도 가능할까요?

3999, 3499 를 비교하면 3>34 가 되지만, 334 와 343 은 343이 더 크게됩니다.

즉, 자기자신을 뒤에 계속 이어붙여줌으로써 문제를 해결할 수 있습니다.

3333, 3434 이런식이 되게 됩니다.

 

방법2 : 스트링을 합친 비교

정말 간단한 방법입니다.

3과 34를 예를 들면

 

sort의 compare 함수를 구현할 때 3+34 와 34+3 을 비교하는 것입니다.

문자열은 결국 334, 343이 되고 343이 더 큰값이 되어 34>3 이 되게끔 바로 정렬이 가능합니다.

 

아래는 방법2로 구현한 코드입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
 
 
bool cmp(string& a, string& b) {
    return (a + b) > (b + a);
}
 
string solution(vector<int> numbers) {
    string answer = "";
    vector<string> v;
    for (int i = 0; i < numbers.size(); i++) v.push_back(to_string(numbers[i]));
 
    sort(v.begin(), v.end(), cmp);
 
    bool check = false;
    for (int i = 0; i < v.size(); i++) {
        answer += v[i];
        if(v[i] != "0") check = true;
    }
    
    if(!check) answer = '0';
 
    return answer;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

 

네.. 11번 테스트케이스가 계속 틀리신다구요? 저도 계속 틀렸습니다

코드 24줄이 보이실 겁니다.

수가 중복된다는 말은 문제설명에 없었습니다.

즉 0이 중복되서 나오게된 케이스만 고려하게 되면, 00000... 이라는 답이 만들어지게 됩니다.

이럴 때는 0만 출력해주시면 됩니다.

'algorithm > programmers' 카테고리의 다른 글

programmers 전화번호 목록  (0) 2020.03.10
programmers H-Index C++  (0) 2020.03.10
programmers K번째수  (0) 2020.03.10
programmers 여행경로  (0) 2020.03.10
programmers 단어 변환  (0) 2020.03.09

programmers : https://programmers.co.kr/learn/courses/30/parts/12198

 

programmers 정렬 level1 K번째수 문제입니다.

 

문제가 어렵지는 않으니 요구하는대로 구현해주시면 됩니다.

 

아래 소스대로 하지않고, 바로 범위간 정렬을 해주셔도 됩니다. (사실 그게 더 빠르긴하겠네요)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
 
vector<int> solution(vector<int> array, vector<vector<int>> commands) {
    vector<int> answer;
 
    int testcase = commands.size();
    for (int i = 0; i < testcase; i++) {
        int a, b, c;
        vector<int> v;
        a = commands[i][0], b = commands[i][1], c = commands[i][2];
        for (int k = a - 1; k < b; k++) v.push_back(array[k]);
        sort(v.begin(), v.end());
        answer.push_back(v[c - 1]);
    }
 
    return answer;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

'algorithm > programmers' 카테고리의 다른 글

programmers H-Index C++  (0) 2020.03.10
programmers 가장 큰 수  (0) 2020.03.10
programmers 여행경로  (0) 2020.03.10
programmers 단어 변환  (0) 2020.03.09
programmers 완주하지 못한 선수  (0) 2020.03.09

+ Recent posts