반응형
반응형

[백준] 1159. 농구경기

Algorithm|2021. 11. 15. 16:18
반응형

 

 

 

1159번: 농구 경기

상근이는 농구의 세계에서 점차 영향력을 넓혀가고 있다. 처음에 그는 농구 경기를 좋아하는 사람이었다. 농구에 대한 열정은 그를 막을 수 없었고, 결국 상근이는 농구장을 청소하는 일을 시작

www.acmicpc.net

 

 

#include <iostream>
#include <vector>
#include <string>

using namespace std;


int main(void)
{
  int n;
  int flag = 0;
  char c;
  string name;
  
  cin >> n;
  
  vector<int> map(26);

  for(int i=0; i<n; i++)
  {
    cin >> name;
    map[name[0]-97]++;
  }

  for(int i=0;i<26;i++)
  {
    if(map[i] >= 5)
    {
      c = 'a'+i;
      cout << c;
      flag = 1;
    }

  }

  if(flag == 0)
    cout << "PREDAJA";

  return 0;
}
반응형

'Algorithm' 카테고리의 다른 글

[백준] 1157. 단어 공부  (0) 2021.11.16
[백준] 1316. 그룹 단어 체커  (0) 2021.11.16
[백준] 5822. 다이얼  (0) 2021.11.15
[백준] 8958. OX퀴즈  (0) 2021.11.15
[Leetcode] 1029. Two City Scheduling  (0) 2021.11.12

댓글()

[백준] 5822. 다이얼

Algorithm|2021. 11. 15. 15:50
반응형

 

 

5622번: 다이얼

첫째 줄에 알파벳 대문자로 이루어진 단어가 주어진다. 단어의 길이는 2보다 크거나 같고, 15보다 작거나 같다.

www.acmicpc.net

#include <iostream>
#include <vector>
#include <string>

using namespace std;


int main(void)
{
  int time = 0;
  string num;
  cin >> num;

  

  for(int i=0;i<num.size();i++)
  {
      if('A'<= num[i] && num[i] <= 'C')
        time += 3;
      else if('D'<= num[i] && num[i] <= 'F')
        time += 4;
      else if('G'<= num[i] && num[i] <= 'I')
        time += 5;
      else if('J'<= num[i] && num[i] <= 'L')
        time += 6;       
      else if('M'<= num[i] && num[i] <= 'O')
        time += 7;
      else if('P'<= num[i] && num[i] <= 'S')
        time += 8;
      else if('T'<= num[i] && num[i] <= 'V')
        time += 9;
      else if('W'<= num[i] && num[i] <= 'Z')
        time += 10;        
  }

  cout << time;
  return 0;
}
반응형

'Algorithm' 카테고리의 다른 글

[백준] 1316. 그룹 단어 체커  (0) 2021.11.16
[백준] 1159. 농구경기  (0) 2021.11.15
[백준] 8958. OX퀴즈  (0) 2021.11.15
[Leetcode] 1029. Two City Scheduling  (0) 2021.11.12
[백준] 2799. 블라인드  (0) 2021.11.09

댓글()

[백준] 8958. OX퀴즈

Algorithm|2021. 11. 15. 15:36
반응형
 

8958번: OX퀴즈

"OOXXOXXOOO"와 같은 OX퀴즈의 결과가 있다. O는 문제를 맞은 것이고, X는 문제를 틀린 것이다. 문제를 맞은 경우 그 문제의 점수는 그 문제까지 연속된 O의 개수가 된다. 예를 들어, 10번 문제의 점수

www.acmicpc.net

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int score(string q);

int main(void)
{

  int n;
  vector<int> s;

  string quiz;
  cin >> n;
  for(int i=0;i<n;i++)
  {
    cin >> quiz;
    s.push_back(score(quiz));
  }

  for(int i=0;i<n;i++)
    cout << s[i]<<'\n';

  return 0;
}


int score(string q)
{
  int acc_score = 0;
  int fin_score = 0;

  for(int i=0;i<q.size();i++)
  {
  
  acc_score++;
    
    if(q[i] == 'O')
      fin_score += acc_score;
    else 
        acc_score = 0;
        
  }
  return fin_score;
}
반응형

'Algorithm' 카테고리의 다른 글

[백준] 1159. 농구경기  (0) 2021.11.15
[백준] 5822. 다이얼  (0) 2021.11.15
[Leetcode] 1029. Two City Scheduling  (0) 2021.11.12
[백준] 2799. 블라인드  (0) 2021.11.09
[백준] 4344. 평균은 넘겠지  (0) 2021.11.09

댓글()

[Leetcode] 1029. Two City Scheduling

Algorithm|2021. 11. 12. 16:21
반응형

 

 

Two City Scheduling - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

 

다해봐도 모르겠어서 가능한 모든 경우의 수를 찾아서 최소값을 구하는 방법을 생각해봤는데

이는 O(n⁴) 까지 고려해야 한다.

 

Main Idea를 찾아본 결과

a와 b의 차이가 가장 큰 경우 작은 값을 이용하면 됐다.

은근 단순해서 화났음

/*
1. costs의 a와 b의 차이와 index를 2차원 배열에 저장
2. gap 값을 기준으로 오름차순 정렬
3. costs size까지 반복하며 순서대로 a,b costs size 절반을 넘지 않도록 더함 
*/


class Solution {
public:
    int twoCitySchedCost(vector<vector<int>>& costs) 
    {
        vector<vector<int>> gap_index;
        int a = 0;
        int b = 0;
        int ans = 0;
        for(int i=0; i<costs.size(); i++) //1과정
        {
            vector<int> v;
            v.push_back(abs(costs[i][0] - costs[i][1]));
            v.push_back(i);
            
            gap_index.push_back(v);           
        }
        
        sort(gap_index.begin(), gap_index.end(), greater<>()); //2과정
        
        
        for(int i=0; i<costs.size(); i++) //3과정
        {
            int idx = gap_index[i][1];
            
            if((costs[idx][0] < costs[idx][1] && a<costs.size()/2) || b>= costs.size()/2) 
            {
                ans += costs[idx][0];
                a++;
            }
            else if((costs[idx][0] >= costs[idx][1] && b<costs.size()/2) || a>= costs.size()/2) 
            {
                ans += costs[idx][1];
                b++;                
            } 
        }    
        
        return ans;
    }
};

실수..

a, b 차이를 내림차순으로 indexing 해야되는데 오름차순해버림 ㅋㅋ;

 

 

 

 

반응형

'Algorithm' 카테고리의 다른 글

[백준] 5822. 다이얼  (0) 2021.11.15
[백준] 8958. OX퀴즈  (0) 2021.11.15
[백준] 2799. 블라인드  (0) 2021.11.09
[백준] 4344. 평균은 넘겠지  (0) 2021.11.09
[Programmers] 스킬트리  (0) 2021.11.07

댓글()

[백준] 2799. 블라인드

Algorithm|2021. 11. 9. 21:13
반응형
 

2799번: 블라인드

첫째 줄에 M과 N이 공백으로 구분해서 주어진다. (1 ≤ M, N ≤ 100) 다음 줄에는 현재 건너편 아파트의 상태가 주어진다. 모든 창문은 문제 설명에 나온 것 처럼 4*4 그리드로 주어진다. 또, 창문과

www.acmicpc.net

 

 

window의 행, 열 축을 반대로 생각해서 고생 좀 함,,,,

창문 타입을 판단하는 부분도 **** 이면, 그냥 else 처리하면 되는데,

else if(w[5*i+5][5*j+1] == '.') 로 생각 없이 적었음 ㅋㅋ

 

#include <iostream>
#include <bits/stdc++.h>
#include <vector>
using namespace std;


int main(void)
{
    int m,n;
    int t;
    vector<int> ans(5);
    
    char w[501][501];
    
    
    cin >> m >> n;
    
    for(int i=0; i<5*m+1;i++) //블라인드 입력
        for(int j=0; j<5*n+1;j++)
            cin >> w[i][j];
    
    for(int i=0; i< m; i++)
    {
        for(int j=0; j< n; j++)
        {
            if(w[5*i+1][5*j+1] == '.')
              {ans[0]++; }  
            else if(w[5*i+2][5*j+1] == '.') 
              {ans[1]++; }
            else if(w[5*i+3][5*j+1] == '.') 
              {ans[2]++; }
            else if(w[5*i+4][5*j+1] == '.') 
              {ans[3]++; }
            else 
              {ans[4]++;}

        }
    }

    for(int i = 0; i<5; i++)
        cout << ans[i] <<" ";
    
    return 0;
}​
반응형

'Algorithm' 카테고리의 다른 글

[백준] 8958. OX퀴즈  (0) 2021.11.15
[Leetcode] 1029. Two City Scheduling  (0) 2021.11.12
[백준] 4344. 평균은 넘겠지  (0) 2021.11.09
[Programmers] 스킬트리  (0) 2021.11.07
[백준] 2920 . 음계  (0) 2021.11.07

댓글()

[백준] 4344. 평균은 넘겠지

Algorithm|2021. 11. 9. 15:54
반응형

 

 

4344번: 평균은 넘겠지

대학생 새내기들의 90%는 자신이 반에서 평균은 넘는다고 생각한다. 당신은 그들에게 슬픈 진실을 알려줘야 한다.

www.acmicpc.net

왜 계속 틀렸나 했는데 마지막에 출력 부분에 '%'를 안 붙임 ㅋㅋ..

#include <iostream>
#include <vector>
#include <numeric>
#include <math.h>
#include <algorithm>

using namespace std;


int main(void)
{
    int c = 0; // case 수
    int s_num; // case 별 학생 수
    double rate = 0;
    int count = 0;
    
    cin >> c ;
    vector<vector<int>> score; //case 별 학생들 점수 vector
    vector<int> v; // score 2차원 확장
    
    
    for(int i=0; i<c; i++) //score 값 저장
    {
        cin >> s_num; 
        score.push_back(v);
        for(int k=0; k<s_num; k++)
        {
            int num=0;
            cin >> num;
            score[i].push_back(num);
    
        }
        
        double sum = std::accumulate(score[i].begin(), score[i].end() , 0.0);
        double mean = sum / score[i].size();
        
        for(int k=0; k<score[i].size(); k++)
        {
            if(mean < score[i][k])
                count +=1;
        } 
        
        rate = 100.0 * count / score[i].size();
        cout.setf(ios::fixed);
        cout.precision(3);
        cout << rate <<'%' <<'\n';
        count = 0;
    }
    

    return 0;
}
반응형

'Algorithm' 카테고리의 다른 글

[Leetcode] 1029. Two City Scheduling  (0) 2021.11.12
[백준] 2799. 블라인드  (0) 2021.11.09
[Programmers] 스킬트리  (0) 2021.11.07
[백준] 2920 . 음계  (0) 2021.11.07
[Leetcode] 455. Assign Cookies  (0) 2021.11.07

댓글()

[Programmers] 스킬트리

Algorithm|2021. 11. 7. 15:15
반응형

조건을 너무 복잡하게 생각했었다.

다시 종이에 그리면서 해보니깐 단순했다.

머쓱 ^^

 

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int solution(string skill, vector<string> skill_trees) 
{
    int answer = 0;
    int flag = 0;

    vector<int> map(26); 
    fill(map.begin(), map.end(), -1);

    for(int i=0; i<skill_trees.size();i++)
    {
        for(int k=0; k<skill.size(); k++) 
        {    
            map[skill[k] - 65] = 21 + k; 
        }//skill_tree의 default 값을 True로 설정
        //21부터 설정한 이유는 skill_trees.size()가 최대 20이기 때문
        
        for(int k=0; k<skill_trees[i].size(); k++) 
        {   
            map[skill_trees[i][k] - 65] = k;
        } //skill_trees별 map 제작


        for(int k=1; k<skill.size(); k++) 
        {    
            if( map[skill[k-1] - 65] >= map[skill[k] - 65] )
                flag = 1;
        } //map내 skill 순서의 index가 오름차순이 아닐 경우 오답 flag

        if(flag == 0)
            answer++;

        flag = 0; //다음 스킬트리를 확인하고자 초기화
        fill(map.begin(), map.end(), -1);

    }

    return answer;
}
반응형

'Algorithm' 카테고리의 다른 글

[백준] 2799. 블라인드  (0) 2021.11.09
[백준] 4344. 평균은 넘겠지  (0) 2021.11.09
[백준] 2920 . 음계  (0) 2021.11.07
[Leetcode] 455. Assign Cookies  (0) 2021.11.07
[Leetcode] 211. Design Add and Search Words Data Structure  (0) 2021.09.28

댓글()

[백준] 2920 . 음계

Algorithm|2021. 11. 7. 14:09
반응형
 

2920번: 음계

다장조는 c d e f g a b C, 총 8개 음으로 이루어져있다. 이 문제에서 8개 음은 다음과 같이 숫자로 바꾸어 표현한다. c는 1로, d는 2로, ..., C를 8로 바꾼다. 1부터 8까지 차례대로 연주한다면 ascending, 8

www.acmicpc.net

 

Boyer-Moore 알고리즘의 아이디어를 따와 풀었다.

 

[Leetcode] 169. Majority Element

Identifying the Problem 최빈값을 찾아라 단 최빈값은 배열 길이 절반 이상 있다. Input: nums = [3,2,3] Output: 3 Input: nums = [2,2,1,1,1,2,2] Output: 2 Organizing thoughts 바로 떠오르는 알고리즘이 ..

gold-goose.tistory.com

ascending이면 7번 연속으로 오른 것이므로 count가 7이고,

descending 이면 7번 연속으로 내린 것이므로 count가 -7이고,

mixed이면 -6~6 사이 값이 나온다.

#include <stdio.h>
#include <iostream>

using namespace std;

int main(void)
{
    int a[8]; #음계 배열
    int count = 0;
    for(int i=0; i<8; i++) #음계 입력
        cin >> a[i];
    
    for(int i=1; i<8; i++)
    {
        if(a[i-1] < a[i])
            count++;
        else
            count--;
    }
    if(count == 7)
        cout << "ascending";
    else if(count == -7)
        cout << "descending";
    else
        cout << "mixed";
       
    return 0;
}
반응형

댓글()

[Leetcode] 455. Assign Cookies

Algorithm|2021. 11. 7. 13:44
반응형

Identifying the Problem

보유한 쿠키로 만족시킬 수 있는 최대한의 아이들의 수를 구한다.

g[ ] : 아이들 별로 만족하는 쿠키 사이즈

s[ ] : 보유한 사이즈별 쿠키

Organizing thoughts

1)  s[j] >= g[i] 꼴을 만족하면 아이에게 쿠키를 줄 수 있다.

2)  아이가 만족하는 쿠키와 주어진 쿠키 사이즈가 최대한 똑같아야 한다.

3) s의 길이가 길든, g의 길이가 길든 탐색은 s 길이만큼 진행해야 한다.

4)  단, s가 더 길 때, 모든 아이들에게 쿠키를 나누어 준 경우, 탐색을 중단한다. 

Sourcecode

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) 
    {
        int k = 0;
        
        sort(g.begin(), g.end()); // g,s를 오름차순 정렬
        sort(s.begin(), s.end());
        
        for(int i = 0; i<s.size(); i++)
        {
            if(g[k] <= s[i])
                k++;
            if(k == g.size()) break;

        }
        return k;
    }
};
반응형

댓글()

[Leetcode] 211. Design Add and Search Words Data Structure

Algorithm|2021. 9. 28. 14:17
반응형

 

Identifying the Problem

Trie 구조, addword, search 기능을 구현한다.

단 search 기능에서 단어 중간에 '.' 이 있는 경우 pass하고 다음 글자로 넘어간다.

 

Example:

wordDictionary.addWord("bad");

wordDictionary.search(".ad"); 

return True

Organizing thoughts

Trie 와 addword는 208번 문제의 코드를 그대로 사용하고, search 부분을 정답코드 참고하였음.

 

 

[Leetcode] 208. Implement Trie (Prefix Tree)

Identifying the Problem Trie Tree를 생성하고, 삽입, 검색, 접두사 검색 (검색엔진의 자동완성) 함수를 구현한다. Organizing thoughts Trie에 관한 내용은 아래 블로그를 참고하였다. [자료구조] 트라이 (Trie)..

gold-goose.tistory.com

https://leetcode.com/problems/design-add-and-search-words-data-structure/discuss/774271/C%2B%2B-oror-Trie-Solution-oror-264-ms-Solution

Sourcecode

class TrieNode 
{
public:
    // TrieNode 객체 생성
    bool finish; //글자의 끝의 유/무 를 finish로 설정
    TrieNode *children[26]; //26개의 자식 노드 생성 ('a~z')
    
    TrieNode() //각 노드의 초기값 설정
    { 
        finish = false;  
        
        for (int i = 0; i < 26; i++)
            children[i] = NULL;
    }//처음 아무것도 없는 상태이므로 각 노드의 끝을 false와 NULL로 설정
};


class WordDictionary {
public:
    WordDictionary() 
    {
        root = new TrieNode(); //Trie 생성    
    }
    
    void addWord(string word) 
    {
        int word_len = word.length(); //단어의 길이
        int k = 0; //string -> int 알파벳 a~z 를 index로 사용하고자 k = 0~25 로 선언
        TrieNode *cur = root; //탐색노드 cur에 초기 TrieNode 대입
        
        for (int i = 0; i < word_len; i++) //단어의 한 글자씩 Trie 에 추가
        {
            k = word[i] - 'a';
            
            if (cur->children[k] == NULL) 
            {
                cur->children[k] = new TrieNode();
            }////해당 trie가 아무것도 없는 상태라면, 새로 하위 노드 생성
            
            cur = cur->children[k]; //다음 node로 이동
        }
        
        cur->finish = true; //단어의 끝 finish 값을 true로 설정 
        
    }
    
    bool search(string word) 
    {
        return searchHelper(word, root); //parameter를 수정한 search 함수
    }
        

    
private:
    TrieNode* root; //root 생성
    
    bool searchHelper(string word, TrieNode* current) 
    {
        for(int i = 0; i < word.size(); i++)
        {
            if(word[i] != '.'){ //기존 search 방식과 동일
                if(!current->children[word[i] - 'a']) 
                    return false;
                current = current->children[word[i] - 'a'];
            }
            else
            { // '.'이 단어 중간에 있는 경우
                for(int j = 0; j < 26; j++) // 다음 자식 노드 26개 모두를 탐색
                {
                    if(current->children[j] && searchHelper(word.substr(i + 1), current->children[j]))
                    { //다음 자식노드가 존재하고, 이후 다음 글자들이 Trie에 있는지 재귀로 탐색
                        return true; //하나라도 만족하면 true리턴
                    }
                }
                return false;
            }
        }
        return current->finish; //'.'이 없는 경우 단어의 끝에 해당하는 Trie->finish 값 리턴
    }
};

 

반응형

댓글()

[Leetcode] 208. Implement Trie (Prefix Tree)

Algorithm|2021. 9. 26. 13:10
반응형

Identifying the Problem

Trie Tree를 생성하고, 삽입, 검색, 접두사 검색 (검색엔진의 자동완성) 함수를 구현한다.

Organizing thoughts

Trie에 관한 내용은 아래 블로그를 참고하였다.

 

[자료구조] 트라이 (Trie) C++ 구현

트라이 (Trie) 우리가 여러 개의 문자열을 가지고 있을 때, 어떤 문자열이 그 문자열 중 하나인지 알아내는 방법을 생각해보자. 단순하게 일일히 비교하는 방법이 있겠지만, 이러한 방법은 매우

eun-jeong.tistory.com

Sourcecode

##source code 출처

 

C++, My solution, easy to understand:) - LeetCode Discuss

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

class TrieNode {
public:
    // TrieNode 객체 생성
    bool finish; //글자의 끝의 유/무 를 finish로 설정
    TrieNode *children[26]; //26개의 자식 노드 생성 ('a~z')
    
    TrieNode() //각 노드의 초기값 설정
    { 
        finish = false;  
        
        for (int i = 0; i < 26; i++)
            children[i] = NULL;
    }//처음 아무것도 없는 상태이므로 각 노드의 끝을 false와 NULL로 설정
};

class Trie {
public:
    Trie() 
    {
        root = new TrieNode(); //Trie 생성
    }

    // 단어를 Trie에 Inserts
    void insert(string word) 
    {
        int word_len = word.length(); //단어의 길이
        int k = 0; //string -> int 알파벳 a~z 를 index로 사용하고자 k = 0~25 로 선언
        TrieNode *cur = root; //탐색노드 cur에 초기 TrieNode 대입
        
        for (int i = 0; i < word_len; i++) //단어의 한 글자씩 Trie 에 추가
        {
            k = word[i] - 'a';
            
            if (cur->children[k] == NULL) 
            {
                cur->children[k] = new TrieNode();
            }////해당 trie가 아무것도 없는 상태라면, 새로 하위 노드 생성
            
            cur = cur->children[k]; //다음 node로 이동
        }
        
        cur->finish = true; //단어의 끝 finish 값을 true로 설정 
    }

    //search 하는 단어가 Trie내에 있다면 true 없다면 false 리턴
    bool search(string word) 
    {
        int word_len = word.length();
        int k = 0;
        TrieNode *cur = root;
        
        for (int i = 0; i < word_len; i++)
        {
            k = word[i] - 'a';
            cur = cur->children[k];
            
            if (cur == NULL)
                return false;
        }
        
        return cur->finish; 
        //insert 글자의 끝 부분을 true로 했을 경우 true 리턴이고 
        //아닐 경우 defalut값이 false이므로 false리턴
    }

    //prefix를 가지는 글자가 있는지 탐색
    bool startsWith(string prefix) 
    {
        int word_len = prefix.length();
        int k = 0;
        TrieNode *cur = root;
        
        for (int i = 0; i < word_len; i++)
        {
            k = prefix[i] - 'a';
            cur = cur->children[k]; //찾는 단어의 글자 순으로 탐색 
            
            if (cur == NULL) //Trie가 NULL이거나, 
                               //탐색할 다음 글자의 node가 NULL인 경우 false return
                return false;
        }
        
        return true; //defalut 값 true
    }

private:
    TrieNode* root; //root 생성
};
반응형

댓글()

[Leetcode] 235. Lowest Common Ancestor of a Binary Search Tree

Algorithm|2021. 9. 19. 13:27
반응형

Identifying the Problem

BST Tree 내의 p와 q의 공통 조상을 찾아 리턴한다.

Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 Output: 6

Explanation: 2와 8의 공통 조상은 6이다.

Organizing thoughts

##아이디어 참고 및 출처

 

C++ Recursive and Iterative - LeetCode Discuss

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

먼저 가능한 경우의 수를 정리해보자 

아래는  p, q가 root기준으로 위치한 곳에 따른 리턴 값이다.

p q return
왼쪽 왼쪽 왼쪽 어딘가
왼쪽 오른쪽 root
오른쪽 오른쪽 오른쪽 어딘가

즉 다음과 같은 경우가 됐을 때, 왼쪽 어딘가 혹은 오른쪽 어딘가를 전위순회로 탐색하다,

왼쪽 p 오른쪽 q가 되는 경우 또는 그 외의 경우

(q의 왼쪽 자손 노드가 p인 경우 or p의 오른쪽 자손 노드가 q인 경우)

root를 return 한다.

Sourcecode

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
    {
        if(root->val > p->val && root->val > q->val) //둘 다 왼쪽
            return lowestCommonAncestor(root->left, p, q); 
        if(root->val < p->val && root->val < q->val) //둘 다 오른쪽
            return lowestCommonAncestor(root->right, p, q);
        return root; //그 이외의 경우 root 리턴
    }
};
반응형

댓글()

[Leetcode] 105. Construct Binary Tree from Preorder and Inorder Traversal

Algorithm|2021. 9. 17. 15:20
반응형

Identifying the Problem

이진트리의 preorder 순회 결과와 inorder 순회 결과를 가지고 원래 트리를 만든다.

 

Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7] 

Output: [3,9,20,null,null,15,7]

Organizing thoughts

탐색

preorder[0]은 트리의 root부분이다.

나머지 부분은 root의 자식 node이다.

임의로 inorder의 요소를 pivot으로 지정했을 때

inorder[0] ~ inorder[pivot-1]의 값들은 pivot의 왼쪽에 위치하고,

inorder[pivot+1] ~ inorder[size-1]의 값들은 pivot의 오른족에 위치한다.

inorder[pivot] 왼쪽에 아무것도 없다면, 왼쪽 자식 노드는 null이고,

inorder[pivot] 오른쪽에 아무것도 없다면, 오른쪽 자식 노드는 null이다.

 

흐름

preorder = [3,9,20,5,7] , inorder = [9,3,5,20,7] 이라면,

pre를 level 별로 놓는다.

 

level  val val
0 3  
1 9 20
2 5 7

그 후에, inorder의 정보로, 자식노드를 결정한다.

순서는 preorder의 순서대로 진행한다.

 

처음 3은 inorder[1]에 위치하고,

inorder[1] 이전은 모두 3 left에 위치, 이후는 모두 right에 위치함을 알 수 있다.

 

다음 9는 inorder[0]에 위치하고,

inorder[0] 왼쪽에 아무것도 없으므로, 왼쪽 노드는 null,

오른쪽에는 3이 있지만, 이미 부모 노드인 것을 확인했으므로 오른쪽 노드도 null이다.

 

다음 20은 inorder[3]에 위치하고,

inorder[3] 이전은 모두 20 left에 위치, 이후는 모두 right에 위치함을 알 수 있다.

왼쪽에 9,3,15가 있지만, 이 중 9,3은 이전에 파악했으므로 왼쪽에 5만 있다고 생각한다.

 

다음 5는 inorder[2]에 위치하고,

왼쪽에 9,3이 있지만, 모두 이전에 파악했으므로, 왼쪽 노드는 null이다.

오른쪽에 20,7이 있지만, 20은 5의 부모노드인 것을 확인했으므로 오른쪽에도 아무것도 없다.

따라서 오른쪽 노드도 null이다.

 

마지막 7은 inorder[4]에 위치하고,

왼쪽은 이미 다 파악했고, 오른쪽은 아무것도 없어 둘다 null이 된다.

Sourcecode

## 정답 코드 및 출처

 

C++ simple recursive (+ detail explanation) - LeetCode Discuss

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) 
    {
        int index = 0; //preorder의 요소를 level 순으로 탐색
        return build(preorder, inorder, index, 0 , inorder.size() - 1);
    }
    TreeNode* build(vector<int>& preorder, vector<int>& inorder,int &index, int left, int right)
    {
        if(left > right) return NULL; //왼쪽 혹은 오른쪽에 아무것도 없다면, null 리턴
        
        int pivot = left; // pivot 초기화
        
        while(inorder[pivot] != preorder[index]) pivot++;
        //preorder[index] 값과 inorder의 같은 부분을 탐색
        
        index++;
        
        TreeNode* node = new TreeNode(inorder[pivot]);
        node->left = build(preorder, inorder, index, left , pivot-1);
        node->right = build(preorder, inorder, index, pivot+1 , right);
        //중위순회로 tree생성
        return node;
    }
};

 

반응형

댓글()

[Leetcode] 230. Kth Smallest Element in a BST

Algorithm|2021. 9. 15. 15:38
반응형

Identifying the Problem

BST 구조 트리의 k번째로 작은 값을 구한다.

Input: root = [5,3,6,2,4,null,null,1], k = 3 Output: 3

Organizing thoughts

Idea[1] : 중위순회를 하며, int vector에 node값 저장 후 , 정렬 , 앞에서 k-1 번째 수 리턴한다.

Idea[2] : 중위순회를 하며, k값을 빼가며 k가 1에 도달했을 때의 값을 리턴한다.

Sourcecode

##Idea[1]

class Solution {
public:
    vector<int> node;
    
    int kthSmallest(TreeNode* root, int& k) 
    {
        inorder(root);
        sort(node.begin(), node.end());
        return node[k-1];
    }
    
    void inorder(TreeNode* root)
    {
        if(root)
        {
            inorder(root->left);
            node.push_back(root->val);
            inorder(root->right);
        }
    }
};

 

##Idea[2] 정답코드 및 출처 

 

 

4 Lines in C++. - LeetCode Discuss

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

class Solution {
public:
    int kthSmallest(TreeNode* root, int& k) 
    {
        if (root) 
        {
            int x = kthSmallest(root->left, k);
            return !k ? x : !--k ? root->val : kthSmallest(root->right, k);
        }
        else return NULL;
    }
};

위 코드는 가독성이 떨어져 가독성이 좋은 코드를 찾아 해설해보았다.

class Solution {
public:
    int kthSmallest(TreeNode* root, int k) { 
        return dfs(root, k);
    }
    int dfs(TreeNode* node, int& k) //int k 가 아니라 int& k 를 사용해 k값을 직접 변경한다.
    {
        if(!node) return NULL; //node가 없다면 null 리턴
        
        int l = dfs(node->left,k); //BST 구조이므로 중위순회
        
        if(k == 0) return l; //전달 받은 node->val 값 리턴, root로 다시 돌아올 때 k가 0인 상태가 된다.
        
        else if(k == 1) //k가 1일 때의 값이 k번 째 값이므로
        {
            k--; //k를 0으로 만들고, 정답 리턴
            return node->val;
        }
        else // k가 1보다 크면, 
        {
            k--; //k를 1 줄이고 (탐색했다는 흔적)
            int r = dfs(node->right,k); //오른쪽으로 중위순회를 이어나간다.
            if(k==0) return r; //오른쪽 탐색결과 정답을 찾았으면 정답 값 리턴
            else return NULL; //오른쪽이 빈노드거나 오른쪽을 탐색해도 못찾으면, null 리턴
        }
    }

};

Mistake

  • tree도 하나의 dp 라고 생각하니 편하다.
  • tree문제 풀 때, 최소단위의 트리를 가정해 생각해보면 수월하다.

New things learned

 

삼항연산자를 이중으로 사용했을 때 이해가 잘 안가 찾아보았다.

 

삼항연산자, 이중 삼항연산자

삼항연산자는 조건 ? true일 경우 실행 내용 : false일 경우 실행 내용 형태의 연산문이다.조건이 충족될 경우 :를 기준으로 앞의 내용이 실행되며, 충족되지 않을 경우 뒷부분의 내용이 실행된다.

velog.io

 

반응형

댓글()

[Leetcode] 98. Validate Binary Search Tree

Algorithm|2021. 9. 14. 15:38
반응형

Identifying the Problem

이진트리를 탐색하며, 왼쪽 하위 트리로 갈수록 값이 작아지고, 오른쪽 하위 트리로 갈 수록 값이 커지는지 판단한다.

Input: root = [5,1,4,null,null,3,6] Output: false

Explanation: root 5의 오른쪽 노드 값이 4로 작아졌다.

Organizing thoughts

// 72 / 80 test cases passed.

class Solution {
public:
    bool isValidBST(TreeNode* root) 
    {
        if(!root) return true;
        //가장 마지막 null은 true로 리턴 (defalut)
        
        if(root->left && root->val <= root->left->val){cout<<"1\n"; return false;} 
        //주어진 조건과 반대가 되는 순간 false를 return
        //root->left, right가 null인 상태에서 val을 접근하면 오류가 나기 때문에
        //left,right가 null이 아니라는 조건을 추가했다.
        if(root->right && root->val >= root->right->val) {cout<<"2\n"; return false;} 
        
        
        return isValidBST(root->left) && isValidBST(root->right); //중위 순회
    }
};

 

Mistake

오른쪽 노드의 값의 왼쪽 노드의 값은 최초 root노드 보다는 작아야 한다.

root < root->right->left < root->right 이런 셈이다 (val은 편의상 생략)

https://leetcode.com/problems/validate-binary-search-tree/discuss/1176115/Why-is-546nullnull37-not-a-valid-BST

Answer Sourcecode

정답코드 출처

 

C++ simple recursive solution - LeetCode Discuss

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

## 전체적인 flow는 나와 유사하다.

left 검사 시에는 이전 값을 최대값으로 두고, 다음으로 넘겼고,

right 검사시에는 이전 값을 최소값으로 두어 다음을 넘긴다.

하지만 내가 실수한 왼쪽과 오른쪽의 세부적인 디테일을 이 코드에선 min과 max를 넘김으로 해결했다.

class Solution {
public:
    
    bool isValidBST(TreeNode* root) 
    {
        return isValidBST(root, NULL, NULL);
    }

    bool isValidBST(TreeNode* root, TreeNode* minNode, TreeNode* maxNode) 
    {
        if(!root) return true;
        if(minNode && root->val <= minNode->val || maxNode && root->val >= maxNode->val)
            return false;
        return isValidBST(root->left, minNode, root) && isValidBST(root->right, root, maxNode);
    }
};

 

반응형

댓글()

[Leetcode] 98. Validate Binary Search Tree

Algorithm|2021. 9. 14. 15:12
반응형

Identifying the Problem

subtree가 tree내에 있다면, true 없다면, false를 리턴한다.

Input: root = [3,4,5,1,2], subRoot = [4,1,2] Output: true

Organizing thoughts

먼저 크게 4가지로 subtree와 tree의 경우를 표로 나타낼 수 있다.

Tree Subtree Result
null null true
o null false
null o false
o o true / false

IDEA

[1] tree를 탐새하면서, tree->val과 subtree->val 이 같은 순간이 오면,

    두 트리를 동시에 탐색하면서 완전히 동일한지 판단한다.

    하지만, 위 예시에서 불필요하게 tree의 level 0과 subtree의 level 0이 동일한지 확인해야한다.

[2] 따라서 1의 단점을 보완해, subtree의 깊이가 같은 곳만 (가장 밑에서의 높이가 같은 곳의 node) 를 뽑아 subtree와        동일한지 판단한다.

[3] tree와 subtree의 값들을 배열에 저장해 subtree 배열의 값이 tree 내에 존재하는지 파악한다.

    하지만, 이는 문제의 의도와는 맞지 않으므로 이 방법으로 풀지는 않겠다.

Sourcecode

소스코드는 2번의 아이디어로 작성되었다.

 

정답 코드의 flow (편의상 subtree의 root를 s, tree의 root를 t로 놓겠다)

 

1. t와 s 둘 다 null이면 true, 둘 중 하나만 null이면 false 리턴

2. s의 깊이를 파악

3. t에서 밑에서 s깊이의 높이에 위치한 노드를 모두 저장

4. 저장된 노드와 s가 같은지 반복하며 비교

 

정답 코드의 출처

 

19ms C++ solution beats 99.9% - LeetCode Discuss

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

class Solution {
    vector<TreeNode*> nodes;

public:
    bool isSubtree(TreeNode* s, TreeNode* t) {
        if (!s && !t) return true; //둘다 null이면 true
        if (!s || !t) return false; //하나만 null이면 false

        getDepth(s, getDepth(t, -1)); //s의 깊이를 구하고, s의 깊이에 해당하는 node저장

        for (TreeNode* n: nodes) //저장한 node들과 s가 같은지 확인
            if (identical(n, t))
                return true;

        return false; //defalut 값 false
    }

    int getDepth(TreeNode* r, int d) 
    {
        if (!r) return -1;
        // -1인 이유 : 1. 가장 아래서부터 높이를 더하기 때문
        //2. t에서 s와 높이가 같은 노드를 저장해야 하는 데, 
        //   s의 높이를 구하는 과정에서 d가 0보다 클 경우, 
        //   저장 node에 s의 node가 들어가는 것을 막고자
        
        int depth = max(getDepth(r->left, d), getDepth(r->right, d)) + 1;
        //중위순회하며 높이 구하기
        
        if (depth == d) //t-node 의 높이가 s의 높이와 같다면 해당 t-node 저장
            nodes.push_back(r);

        return depth;
    }

    bool identical(TreeNode* a, TreeNode* b) 
    {
        if (!a && !b) return true; //둘다 null이면 true
        if (!a || !b || a->val != b->val) return false; 
        //하나만 null이면 혹은 둘의 값이 다르면 false 

        return identical(a->left, b->left) && identical(a->right, b->right);
        //false 가 하나라도 잡히면 false 리턴
    }
};

 

반응형

댓글()

[Leetcode] 102. Binary Tree Level Order Traversal

Algorithm|2021. 9. 11. 12:35
반응형

Identifying the Problem

이진트리의 레벨별로의 값들을 묶어 2차원 벡터로 리턴한다.

 

 

Input: root = [3,9,20,null,null,15,7] Output: [[3],[9,20],[15,7]]

Organizing thoughts

이진 트리의 탐색 깊이가 깊어질 때,

2차원 벡터의 size를 하나 씩 늘리며,

해당 깊이에 해당하는 값을 2차원 벡터에 추가한다.

Sourcecode

class Solution {
    
public:
    vector<vector<int>> ans; //정답 벡터
    int max_depth = 0; 
    //resize가 줄어들게 되면, 기존 값들이 다 없어지기에, 최대 size를 유지해준다.
    
    vector<vector<int>> levelOrder(TreeNode* root) 
    {
        if(!root) return ans; //빈 트리면 null 리턴
        
        ans.push_back(vector<int>()); //행 추가
	    ans[0].push_back(root->val); //root 값 추가
        
        insert(root->left,1); //재귀로 깊이 탐색
        insert(root->right,1);
        
        return ans;
    }
    void insert(TreeNode* root, int c)
    {
        if(!root) return;
        
        else
        {
            max_depth = c > max_depth? c : max_depth; //깊이가 늘어나면 최대 깊이 수정
            ans.resize(max_depth+1); //최대 깊이에 맞게 size 수정한다.
            ans[c].push_back(root->val); //레벨에 맞는 곳에 값 추가
            
            insert(root->left,c+1);
            insert(root->right,c+1);
        }
    }
};

 

New things learned

  • c++ resize를 사용시 size가 5였다가 3으로 다시 준다면, size가 5였을 때 값은 다 날라간다.
 

c++ vector reserve vs resize : 미리 공간을 만들어 놓고 쓰면 안 될까요?

 예전에 vector가 인자로 들어왔을 때, 어떻게 해야 되는지를 올렸습니다. 어느 분이 댓글로 피드백을 주셨습니다. 그 내용에 관해서 보강 설명을 하도록 하겠습니다. 사실 동적 배열에서 중요한

codingdog.tistory.com

 

반응형

댓글()

[Leetcode] 124. Binary Tree Maximum Path Sum

Algorithm|2021. 9. 11. 11:34
반응형

Identifying the Problem

이진트리를 순회하면서, 가장 큰 path sum을 구한다.

단, 노드는 최대 한번만 path에 나타나야한다.

Input: root = [-10,9,20,null,null,15,7]

Output: 42

Explanation: The optimal path is 15 -> 20 -> 7 with a path sum of 15 + 20 + 7 = 42.

Organizing thoughts

tree를 중위 순회하면서, 합을 누적시키다가, 합이 음수가 되면,

sum을 다시 0으로 초기화하고 최대값을 구해 나간다.

 

하지만 이렇게 쉽게 풀리면 hard가 아니라 easy이다.

작성한 코드를 제출했지만 내가 생각한 답과 달랐다.

Mistake

path의 개념을 잘못 이해했다.

하나의 선이 있다면 그 선이 노드에 한번만 걸쳐가게 해야하는데,

그 선이 노드를 두번 걸치게 되는 줄 알았다.

중위 탐색의 순서를 배열로 생각했을 때 가장 큰 max subarray를 구하는 문제로 착각했던 것이다.

빨간색 path가 아니라 파란색 path가 되어야 한다

 

Sourcecode

## 내가 짠 코드

class Solution {
    int sum = 0;
public:
    int maxPathSum(TreeNode* root) 
    {

        
        if(!root) return 0;
        
        maxPathSum(root->left);
        sum+=root->val;
        cout<< sum << '\n';
        if(sum < 0) sum  = 0;
        maxPathSum(root->right);
        
        return sum;
    }
};

## 정답 코드 및 출처

 

[recommend for beginners]clean C++ implementation with detailed explanation - LeetCode Discuss

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

이 곳에서 각 tree 별 case를 확인 할 수 있다.

 

[Leetcode][124] Binary Tree Maximum Path Sum

문제 : https://leetcode.com/problems/binary-tree-maximum-path-sum/ 서브트리의 루트 노드를 기준으로 만들 수 있는 sequence들은 다음과 같다. 1. 현재 루트노드, 루트노드의 왼쪽, 오른쪽 노드를 sequenc..

withhamit.tistory.com

class Solution {
    int sum;
public:
    int maxPathSum(TreeNode* root) 
    {

        sum = INT_MIN; //적어도 최소 하나는 더해야 하기에 
        			   //0이 아닌, 가장 작은 int값을 최소값으로 설정
        help(root);
        return sum;
    }
    
    int help(TreeNode* root)
    {
        if(!root) return 0; //재귀 탈출
        
        int left = max(0,help(root->left)); //case 2
        int right = max(0,help(root->right)); //case 3
        
        sum = max(sum , left + right + root->val); 
        //case 1 : root와 left,right가 기존 sum 보다 크다면 셋의 합을 sum으로 한다.
        
        return max(left,right) + root->val;  
        //case 4 left, right가 음수면, left와 right를 정하는 과정에서 l,r을 버린다. 
    }
};
반응형

댓글()

[Leetcode] 226. Invert Binary Tree

Algorithm|2021. 9. 9. 19:10
반응형

Identifying the Problem

모든 이진트리를 뒤집는다.

Organizing thoughts

Sourcecode

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) 
    {
        if(!root) return NULL; //탈출 조건
        
        swap(root->left, root->right); //왼쪽과 오른쪽 node를 뒤집음
        
        invertTree(root->left); //재귀 탐색
        invertTree(root->right);
            
        return root;
    }
};

 

반응형

댓글()

[Leetcode] 104. Maximum Depth of Binary Tree

Algorithm|2021. 9. 9. 18:58
반응형

Identifying the Problem

이진트리의 최대 깊이를 구한다.

Organizing thoughts

정답 참고 출처

 

 

8ms Recursive/BFS C++ Solutions - LeetCode Discuss

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

 

tree의 속성인 재귀를 활용해 트리의 깊이를 들어갈 때마다, 

1을 누적해서 더하고, 왼쪽과 오른쪽의 트리의 깊이를 비교하며

최대를 구한다.

 

 

 

 

Sourcecode

class Solution {
public:
    int maxDepth(TreeNode* root) 
    {
        return root ? 1 + max(maxDepth(root->left), maxDepth(root->right)): 0;
    }
};

 

반응형

댓글()