인프런 커뮤니티 질문&답변

yjs000616님의 프로필 이미지
yjs000616

작성한 질문수

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

2-R

2-R 질문합니다.

작성

·

209

·

수정됨

0

- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.


안녕하세요 큰돌님.

<1번 코드>

#include <iostream>
#include <vector>
using namespace std;

int n, root, del, visited[53], cnt;
vector<int> v[53];
bool isLeaf;

void dfs(int n){
    visited[n]= 1;
    isLeaf=true;

    for(int i : v[n]){
        if(!visited[i] && i != del){
            //방문하지 않았고 현재 i가 del이랑 다르면 dfs를 계속 호출해서 탐색해야 함
            isLeaf = false;
            dfs(i);
        }
    }

    if(isLeaf){
        cnt++;
    }

}

int main(){

    cin >> n;

    int num;
    for(int i=0; i<n; i++){
        cin >> num;
        
        if(num == -1){
            root = i;
        }else{
            v[num].push_back(i);
        }
    }

    cin >> del;

    if(del == root){
        cout << 0 << "\n";
    }else{
        dfs(root);
        cout << cnt << "\n";
    }


    return 0;
}
#include <iostream>
#include <vector>
using namespace std;

int n, root, del, visited[53], cnt;
vector<int> v[53];

void dfs(int n){
    visited[n]= 1;
    bool isLeaf = true;     //가지마다 체크해야하니까

    for(int i : v[n]){
        if(!visited[i] && i != del){
            //방문하지 않았고 현재 i가 del이랑 다르면 dfs를 계속 호출해서 탐색해야 함
            isLeaf = false;
            dfs(i);
        }
    }

    if(isLeaf){
        cnt++;
    }

}

int main(){

    cin >> n;

    int num;
    for(int i=0; i<n; i++){
        cin >> num;
        
        if(num == -1){
            root = i;
        }else{
            v[num].push_back(i);
        }
    }

    cin >> del;

    if(del == root){
        cout << 0 << "\n";
    }else{
        dfs(root);
        cout << cnt << "\n";
    }


    return 0;
}

처음에 첫번째 코드로 작성하여 리프 노드의 갯수가 제대로 출력되지 않았습니다. isLeaf라는 변수의 선언 위치에 따라 값이 달라지는데 왜 두 코드가 값이 다르게 나오는지 모르겠습니다..

답변 2

0

큰돌님의 프로필 이미지
큰돌
지식공유자

안녕하세요 yjs님 ㅎㅎ

    bool isLeaf = true;     //가지마다 체크해야하니까

    for(int i : v[n]){
        if(!visited[i] && i != del){
            //방문하지 않았고 현재 i가 del이랑 다르면 dfs를 계속 호출해서 탐색해야 함
            isLeaf = false;
            dfs(i);
        }
    }

    if(isLeaf){
        cnt++;
    }

이 코드에서 isLeaf가 의미하는 바는 해당 노드를 중심으로 재귀함수들을 호출하면서 방문하지 않은 ... 정점들을 탐색해서 그게 맞다면 false를 반환하죠?

근데 이 코드는 이 함수에만 국한됩니다. 즉, isLeaf가 다른 dfs함수에 영향을 주지 않습니다.

 

bool isLeaf;

void dfs(int n){
    visited[n]= 1;
    isLeaf=true;

하지만 이코드는 다른 dfs에서 바뀌어질 가능성이 있습니다.

즉,

A - dfs에서 isLeaf가 처음에 true를 기반으로 로직이 수행되어야 하는데

B - dfs에서 갑자기 false로 변환되면 A - dfs에 영향을 끼치게 되는 것이죠.

 

사실 이에 대한 강의는 제가 제작했는데요. ㅎㅎ

https://www.inflearn.com/course/lecture?courseSlug=10%EC%A3%BC%EC%99%84%EC%84%B1-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%81%B0%EB%8F%8C&unitId=144194&tab=curriculum

이 강의 참고 부탁드립니다.



또 질문 있으시면 언제든지 질문 부탁드립니다.

좋은 수강평과 별점 5점은 제게 큰 힘이 됩니다. :)

감사합니다.

강사 큰돌 올림.


 

0

안녕하세요, 인프런 AI 인턴입니다. yjs000616님, 제시해주신 코드와 관련하여 리프 노드 카운트 문제로 나타나는 차이점에 대한 해명을 요청하신 것으로 이해합니다.

두 코드 사이의 차이점에 대해 해결책을 제시한 유사한 답변을 여기에 링크합니다:

제시된 링크들의 답변은 dfs 함수를 사용하여 리프 노드를 카운트하는 문제에 대한 질문을 다루고 있습니다. 특히, 지식공유자는 트리 구조에서 각 노드의 자식 노드가 없는 경우, 즉 리프 노드에 대해 카운트를 증가시키는 올바른 방법을 설명하고 있습니다.

질문에 대한 답변을 보다 자세히 알고 싶으시다면, 위 링크를 방문하여 확인해보시는 것을 추천합니다.

제시된 질문의 핵심 주제는 dfs (Depth-First Search) 재귀함수를 통해 트리 구조상에서 리프 노드의 개수를 정확하게 파악하는 방법에 관한 것입니다. 이것은 알고리즘 문제 해결에서 매우 일반적인 시나리오입니다. 첫 번째 코드와 두 번째 코드 사이의 차이점은 isLeaf 변수의 범위와 선언 위치입니다.

첫 번째 코드에서는 isLeafdfs 함수의 전역변수처럼 작동하며, 따라서 dfs 함수가 재귀적으로 호출될 때마다 그 값이 유지되지 않고 마지막 호출값에 의해 영향을 받을 수 있는 반면, 두 번째 코드에서는 isLeaf가 각 재귀 단계마다 새로 선언됩니다. 따라서 각 노드의 리프 노드 여부를 정확히 결정할 수 있습니다. 이로 인해 리프 노드의 카운트가 정확하게 되거나, 잘못되어 다르게 카운트 될 수 있는 주요 차이점입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

yjs000616님의 프로필 이미지
yjs000616

작성한 질문수

질문하기