공부기록

후보키 본문

코테/프로그래머스

후보키

코타쿠 2021. 5. 5. 17:37
  • 문제

https://programmers.co.kr/learn/courses/30/lessons/42890#

 

코딩테스트 연습 - 후보키

[["100","ryan","music","2"],["200","apeach","math","2"],["300","tube","computer","3"],["400","con","computer","4"],["500","muzi","music","3"],["600","apeach","music","2"]] 2

programmers.co.kr

  • 코드
더보기
import java.util.*;

class Solution {
    int count = 0;
    public int solution(String[][] relation) {
        int answer = 0;
        
        boolean check[] = new boolean[relation[0].length];
        boolean record[] = new boolean[relation[0].length];
        boolean mid_rec[] = new boolean[relation[0].length];
        for(int i=0; i<check.length; i++){
            check[i] = false;
            record[i] = false;
            mid_rec[i] = false;
        }
        
        for(int i=1; i<=check.length; i++){
            
            dfs(relation, check, record, mid_rec, 0, i);
            for(int j=0; j<mid_rec.length; j++){
                if(mid_rec[j]){
                    record[j] = mid_rec[j];
                    mid_rec[j] = false;
                }
            }
        }
        
        answer = count;
        
        return answer;
    }
    
    boolean findAns(String[][] relation, boolean check[]){
        HashMap<String, Boolean> key_count = new HashMap<>();
        for(int i=0; i<relation.length; i++){
            String curKey = "";
            for(int j=0; j<relation[i].length; j++){
                if(check[j])
                    curKey += (relation[i][j] + "/");
            }
            if(key_count.get(curKey) != null)
                return false;
            else
                key_count.put(curKey, true);
        }
        return true;
    }
    
    void dfs(String[][] relation, boolean check[], boolean record[], boolean mid_rec[], int cur_idx, int left_count){
        if(left_count == 0){
            if(this.findAns(relation, check)){
                for(int i=0; i<check.length; i++)
                    if(check[i])
                        mid_rec[i] = check[i];
                count++;
            }
        }else if(cur_idx == check.length){
            return;
        }else{
            if(record[cur_idx] == false){
                check[cur_idx] = true;
                this.dfs(relation, check, record, mid_rec, cur_idx+1, left_count-1);
                check[cur_idx] = false;
            }
            this.dfs(relation, check, record, mid_rec, cur_idx+1, left_count);            
        }
    }
    
    
}

 

더보기
import java.util.*;

class Solution {
    int count = 0;
    public int solution(String[][] relation) {
        int answer = 0;
        
        boolean check[] = new boolean[relation[0].length];
        ArrayList<String> keyArr = new ArrayList<>();
        
        for(int i=0; i<check.length; i++){
            check[i] = false;
        }
        
        for(int i=1; i<=check.length; i++){   
            dfs(relation, keyArr, check, 0, i);
        }
        
        boolean his[] = new boolean[keyArr.size()];
        String strArr[] = new String[keyArr.size()];
        for(int i=0; i<strArr.length; i++)
            strArr[i] = keyArr.get(i);
        
        Arrays.sort(strArr, (s1, s2)->Integer.compare(s1.length(), s2.length()));

        
        for(int i=0; i<strArr.length; i++){
            if(his[i])
                continue;
            else
                count++;
            for(int j=i+1; j<strArr.length; j++){
                if(strArr[j].contains(strArr[i])){
                    his[j] = true;
                }
            }
        }
        
        answer = count;
        
        return answer;
    }
    
    boolean findAns(String[][] relation, boolean check[]){
        HashMap<String, Boolean> key_count = new HashMap<>();
        for(int i=0; i<relation.length; i++){
            String curKey = "";
            for(int j=0; j<relation[i].length; j++){
                if(check[j])
                    curKey += (relation[i][j] + "/");
            }
            if(key_count.get(curKey) != null)
                return false;
            else
                key_count.put(curKey, true);
        }
        return true;
    }
    
    void dfs(String[][] relation, ArrayList<String> keyArr, boolean check[], int cur_idx, int left_count){
        if(left_count == 0){
            if(this.findAns(relation, check)){
                String curKey = "";
                for(int i=0; i<check.length; i++)
                    if(check[i])
                        curKey += Integer.toString(i);
                keyArr.add(curKey);
            }
        }else if(cur_idx == check.length){
            return;
        }else{
            check[cur_idx] = true;
            this.dfs(relation, keyArr, check, cur_idx+1, left_count-1);
            check[cur_idx] = false;
            this.dfs(relation, keyArr, check, cur_idx+1, left_count);            
        }
    }
    
    
}

 

더보기
import java.util.*;

class Solution {
    int count = 0;
    public int solution(String[][] relation) {
        int answer = 0;
        
        boolean check[] = new boolean[relation[0].length];
        ArrayList<Integer> keyArr = new ArrayList<>();
        
        for(int i=0; i<check.length; i++){
            check[i] = false;
        }
        
        for(int i=1; i<=check.length; i++){   
            dfs(relation, keyArr, check, 0, i);
        }
        
        Collections.sort(keyArr);
        boolean his[] = new boolean[keyArr.size()];
        for(int i=0; i<keyArr.size(); i++)
            his[i] = false;
        for(int i=0; i<keyArr.size(); i++){
            int a = keyArr.get(i);
            if(his[i])
                continue;
            count++;
            for(int j=i+1; j<keyArr.size(); j++){
                int b = keyArr.get(j);
                if(a == (a&b))
                    his[j] = true;
            }
        }
        
  
        answer = count;
        
        return answer;
    }
    
    boolean findAns(String[][] relation, boolean check[]){
        HashMap<String, Boolean> key_count = new HashMap<>();
        for(int i=0; i<relation.length; i++){
            String curKey = "";
            for(int j=0; j<relation[i].length; j++){
                if(check[j])
                    curKey += (relation[i][j] + "/");
            }
            if(key_count.get(curKey) != null)
                return false;
            else
                key_count.put(curKey, true);
        }
        return true;
    }
    
    void dfs(String[][] relation, ArrayList<Integer> keyArr, boolean check[], int cur_idx, int left_count){
        if(left_count == 0){
            if(this.findAns(relation, check)){
                int curKey = 0;
                int cursor = 1;
                for(int i=0; i<check.length; i++, cursor = cursor<<1)
                    if(check[i])
                        curKey += cursor;
                keyArr.add(curKey);
            }
        }else if(cur_idx == check.length){
            return;
        }else{
            check[cur_idx] = true;
            this.dfs(relation, keyArr, check, cur_idx+1, left_count-1);
            check[cur_idx] = false;
            this.dfs(relation, keyArr, check, cur_idx+1, left_count);            
        }
    }
    
    
}
  • 피드백
    • 1차 시도
      • 후보키들중 하나의 후보키에 이미 쓰인 값이 다른 후보키에 들어갈 수 있었다. 1차 시도는 그래서 실패
    • 2차 시도
      • 그래서 모든 key들을 구해서 string으로 contains해서 풀려고 했는데... 다음과 같은 경우가 있다.
      • 후보키 AC, 유일성이 있는 AKC... 이 경우 AKC는 답으로 인정될 수 없지만 contains하면 AKC는 걸러지지 않아 답으로 처리해버린다.
      • 중간에 있는 것 까지 처리할 수 있는 것은 결국 속성별로 idx를 주어 겹쳐지는지 확인하는 방법이고 이는 비트 마스킹으로 O(1)만에 해결할 수 있다.
      • 이와 같이 연속적이지 않은 원소들의 집합을 연속적이라고 착각하지 말자.

'코테 > 프로그래머스' 카테고리의 다른 글

퍼즐 조각 채우기 (위클리 챌린지 3주차)  (0) 2021.08.17
디스크 컨트롤러  (0) 2021.05.20
임시  (0) 2021.05.05
경주로 건설  (0) 2021.05.04
괄호변환  (1) 2021.05.03