posted by 코딩 공부중 2022. 4. 19. 15:12
  • 단어 변환
문제 설명

두 개의 단어 begin, target과 단어의 집합 words가 있습니다. 아래와 같은 규칙을 이용하여 begin에서 target으로 변환하는 가장 짧은 변환 과정을 찾으려고 합니다.

1. 한 번에 한 개의 알파벳만 바꿀 수 있습니다.
2. words에 있는 단어로만 변환할 수 있습니다.

예를 들어 begin이 "hit", target가 "cog", words가 ["hot","dot","dog","lot","log","cog"]라면 "hit" -> "hot" -> "dot" -> "dog" -> "cog"와 같이 4단계를 거쳐 변환할 수 있습니다.

두 개의 단어 begin, target과 단어의 집합 words가 매개변수로 주어질 때, 최소 몇 단계의 과정을 거쳐 begin을 target으로 변환할 수 있는지 return 하도록 solution 함수를 작성해주세요.

제한사항
  • 각 단어는 알파벳 소문자로만 이루어져 있습니다.
  • 각 단어의 길이는 3 이상 10 이하이며 모든 단어의 길이는 같습니다.
  • words에는 3개 이상 50개 이하의 단어가 있으며 중복되는 단어는 없습니다.
  • begin과 target은 같지 않습니다.
  • 변환할 수 없는 경우에는 0를 return 합니다.
입출력 예begintargetwordsreturn
"hit" "cog" ["hot", "dot", "dog", "lot", "log", "cog"] 4
"hit" "cog" ["hot", "dot", "dog", "lot", "log"] 0
입출력 예 설명

예제 #1
문제에 나온 예와 같습니다.

예제 #2
target인 "cog"는 words 안에 없기 때문에 변환할 수 없습니다.

import java.util.*;

class Solution {
   static HashMap<String,Boolean>check;
    
    private int bfs(String begin, String target, String[] words){
        Queue<String> queue = new LinkedList<>();   //큐 선언
        queue.add(begin);   //큐에 첫 문자열 담기
        check.put(begin,true); //첫 문자열 방문 처리
        int answer=0;
        while(!queue.isEmpty()){
            String s = queue.poll();
            ArrayList<String> checkStr = findStr(s,words);
            
            System.out.println("Hello Java s "+s);
            System.out.println("Hello Java checkStr "+checkStr);
            //찾을 수 있는 단어 중 타겟에서 한단어 차이나는게 존재하면 바로 해당 단어로 변환해주기
            int value = 0;
            String tagetTmp = "";
            for(int i=0; i<checkStr.size(); i++){
                if(!check.get(checkStr.get(i))){    //방문하지 않은 단어일때
                    value = findTarget(checkStr.get(i),target);
                }
                if(value==1){
                    tagetTmp = checkStr.get(i);
                }
            }
            System.out.println("Hello Java tagetTmp "+tagetTmp);
            System.out.println("Hello Java value "+value);
            for(int i=0; i<checkStr.size(); i++){
                if(!check.get(checkStr.get(i))){    //방문하지 않은 단어일 
                    check.put(checkStr.get(i),true);    //우선 방문체크
                    if(value==0){
                        queue.add(checkStr.get(i));
                    } else if(value==1) {
                        //바로 이동할 수 있는 경우
                        queue.poll();
                        queue.add(tagetTmp);
                    }
                }
            }
            System.out.println("Hello Java answer "+queue.toString());
            answer++;
            for (String q:queue) {
                if (q.equals(target)) return answer;
            }
        }
        return 0;
    }
    private int findTarget(String str, String target){
        int val = 0;
        for(int i=0; i<str.length(); i++){
            if(str.charAt(i)!=target.charAt(i)){      //같지 않을 경우
                val++;
            }
        }
        if(val==1){
            return 1;
        }
        return 0;
    }
    
    private ArrayList<String> findStr(String str, String[] words){
        ArrayList<String> list = new ArrayList<>();
        String[] tmp = str.split(""); //비교대상 문자열
          
        for(String word : words){
            String[] wordTmp = word.split("");    //비교할 문자열
            int val = 0;
            
            for(int i=0; i<wordTmp.length; i++){
                if(!wordTmp[i].equals(tmp[i])){      //같지 않을 경우
                    val++;
                }
            }
            if(val==1){
                if(!check.get(word)){    //방문하지 않은 단어일 경우
                    list.add(word); //하나만 같을 경우 변경 가능
                }
            }
        }
        return list;
    }
    
    public int solution(String begin, String target, String[] words) {
        int answer = 0;
        check=new HashMap<String,Boolean>();
        for(String tmp : words){
            //System.out.println("Hello Java answer "+tmp);
            check.put(tmp,false);
        }
        answer = bfs(begin,target,words);
        
        return answer;
    }
}

bfs/dfs를 활용해서 푸는 문제

테스트케이스 1번이 통과가 안되는데 문제는 정답으로 처리되는 문제가 발생해서

여기저기 뜯어고쳐봄 테스트케이스는 전부 통과하고 정답처리까지 받았으나

다른 케이스를 추가했더니 또 안되는 상황이 발생함

문제가 이상한건지 확인 필요..

 

 

posted by 코딩 공부중 2022. 3. 30. 17:33

문제 설명

명함 지갑을 만드는 회사에서 지갑의 크기를 정하려고 합니다. 다양한 모양과 크기의 명함들을 모두 수납할 수 있으면서, 작아서 들고 다니기 편한 지갑을 만들어야 합니다. 이러한 요건을 만족하는 지갑을 만들기 위해 디자인팀은 모든 명함의 가로 길이와 세로 길이를 조사했습니다.

아래 표는 4가지 명함의 가로 길이와 세로 길이를 나타냅니다.

명함 번호가로 길이세로 길이
1 60 50
2 30 70
3 60 30
4 80 40

가장 긴 가로 길이와 세로 길이가 각각 80, 70이기 때문에 80(가로) x 70(세로) 크기의 지갑을 만들면 모든 명함들을 수납할 수 있습니다. 하지만 2번 명함을 가로로 눕혀 수납한다면 80(가로) x 50(세로) 크기의 지갑으로 모든 명함들을 수납할 수 있습니다. 이때의 지갑 크기는 4000(=80 x 50)입니다.

모든 명함의 가로 길이와 세로 길이를 나타내는 2차원 배열 sizes가 매개변수로 주어집니다. 모든 명함을 수납할 수 있는 가장 작은 지갑을 만들 때, 지갑의 크기를 return 하도록 solution 함수를 완성해주세요.


제한사항
  • sizes의 길이는 1 이상 10,000 이하입니다.
    • sizes의 원소는 [w, h] 형식입니다.
    • w는 명함의 가로 길이를 나타냅니다.
    • h는 명함의 세로 길이를 나타냅니다.
    • w와 h는 1 이상 1,000 이하인 자연수입니다.

입출력 예sizesresult
[[60, 50], [30, 70], [60, 30], [80, 40]] 4000
[[10, 7], [12, 3], [8, 15], [14, 7], [5, 15]] 120
[[14, 4], [19, 6], [6, 16], [18, 7], [7, 11]] 133

입출력 예 설명

입출력 예 #1
문제 예시와 같습니다.

입출력 예 #2
명함들을 적절히 회전시켜 겹쳤을 때, 3번째 명함(가로: 8, 세로: 15)이 다른 모든 명함보다 크기가 큽니다. 따라서 지갑의 크기는 3번째 명함의 크기와 같으며, 120(=8 x 15)을 return 합니다.

입출력 예 #3
명함들을 적절히 회전시켜 겹쳤을 때, 모든 명함을 포함하는 가장 작은 지갑의 크기는 133(=19 x 7)입니다.

 

import java.util.*;

class Solution {
    public int solution(int[][] sizes) {
        int answer = 0;
        //1.가로에 제일 큰값
        //2.세로에 제일 작은 값 모아두기
        ArrayList<Integer> left = new ArrayList<>();
        ArrayList<Integer> right = new ArrayList<>();
        
        for(int i=0; i<sizes.length; i++){
            if(sizes[i][0]>=sizes[i][1]){
                left.add(sizes[i][0]);
                right.add(sizes[i][1]);
            } else{
                left.add(sizes[i][1]);
                right.add(sizes[i][0]);
            }
        }
        System.out.println("Hello Java "+left);
        System.out.println("Hello right "+right);
        //각 리스트 최대값 곱하기
        int max1 = Collections.max(left);
        int max2 = Collections.max(right);
        
        
        return max1*max2;
    }
}

핵심은 최대값 최소값을 이용하는 것

math를 쓴 경우가 많은데 나는 collections을 사용함

posted by 코딩 공부중 2022. 3. 30. 17:31

문제 설명

가로 길이가 Wcm, 세로 길이가 Hcm인 직사각형 종이가 있습니다. 종이에는 가로, 세로 방향과 평행하게 격자 형태로 선이 그어져 있으며, 모든 격자칸은 1cm x 1cm 크기입니다. 이 종이를 격자 선을 따라 1cm × 1cm의 정사각형으로 잘라 사용할 예정이었는데, 누군가가 이 종이를 대각선 꼭지점 2개를 잇는 방향으로 잘라 놓았습니다. 그러므로 현재 직사각형 종이는 크기가 같은 직각삼각형 2개로 나누어진 상태입니다. 새로운 종이를 구할 수 없는 상태이기 때문에, 이 종이에서 원래 종이의 가로, 세로 방향과 평행하게 1cm × 1cm로 잘라 사용할 수 있는 만큼만 사용하기로 하였습니다.
가로의 길이 W와 세로의 길이 H가 주어질 때, 사용할 수 있는 정사각형의 개수를 구하는 solution 함수를 완성해 주세요.

제한사항
  • W, H : 1억 이하의 자연수

입출력 예

WHresult
8 12 80
입출력 예 설명

입출력 예 #1
가로가 8, 세로가 12인 직사각형을 대각선 방향으로 자르면 총 16개 정사각형을 사용할 수 없게 됩니다. 원래 직사각형에서는 96개의 정사각형을 만들 수 있었으므로, 96 - 16 = 80 을 반환합니다.

class Solution {
    int gcd(int num1, int num2){
        if(num2 == 0) return num1;
        else return gcd(num2, num1 % num2);
    }
    
    
    public long solution(int w, int h) {
        long answer = 1;
        int gcd = gcd(w,h);
        answer = (long)((long)w*(long)h) - ((((long)w/gcd + (long)h/gcd) -1) * gcd);
        return answer;
    }
}

공식 찾는게 정말 힘들었다

그리고 정답 보낼 때 자료형 long으로 맞춰줘야만 케이스 통과 가능