자료구조와 알고리듬 With Java/[Study] BAEKJOON 프로그래머스 CodeUp LeetCode

2022-07-27 [8회차] 알고리즘 스터디

계란💕 2022. 7. 26. 15:45

1. 카카오 프렌즈 컬러링북 - lv 2

출처  https://school.programmers.co.kr/learn/courses/30/lessons/1829

 

프로그래머스

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

programmers.co.kr

 

  MySol) 9.1ms

    - 전형적인 DFS알고리즘 문제이다.

java
열기

 

  Sol) 재귀함수 - 9.32ms

    - 내가 구현한 DFS와 거의 같은데 Direction 행렬 쓰지 않는다는 점이랑 ArrayList<>에 영역의 크기를 저장하는 것만 다르다.

java
열기

 

  Note) 유사한 문제 - 실버 1

출처 백준 단지번호 붙이기https://www.acmicpc.net/problem/2667

 

2667번: 단지번호붙이기

<그림 1>과 같이 정사각형 모양의 지도가 있다. 1은 집이 있는 곳을, 0은 집이 없는 곳을 나타낸다. 철수는 이 지도를 가지고 연결된 집의 모임인 단지를 정의하고, 단지에 번호를 붙이려 한다. 여

www.acmicpc.net

  MySol) 224ms

java
열기

    - 컬러링북은 영역의 개수, 가장 큰 영역의 크기를 반환하는데 백준(단지 번호 붙이기)문제는 영역 개수와 영역별로 크기를 모두 반환하도록 한다.

      -> DFS()를 실행한 다음의 if문에서 cntfmf result.add()한다.

   - 컬러링 북은 원소로  다양한 정숫값이 올 수 있는데 백준 문제는 0, 1로만 이루어진다는 점이 다르다.

   

 

  Sol) 스터디원 블로그: https://guiwoo.tistory.com/

 

java
열기

 

 

 

2.   숫자 야구 - 완전 탐색

https://www.acmicpc.net/problem/2503

 

2503번: 숫자 야구

첫째 줄에는 민혁이가 영수에게 몇 번이나 질문을 했는지를 나타내는 1 이상 100 이하의 자연수 N이 주어진다. 이어지는 N개의 줄에는 각 줄마다 민혁이가 질문한 세 자리 수와 영수가 답한 스트

www.acmicpc.net

   Note) 입출력 예시

<hide/>
[입력]
4
123 1 1
356 1 0
327 2 0
489 0 1

[출력]
2

 

   Sol) 스터디원 - 88ms

 스터디원 블로그: https://guiwoo.tistory.com/

java
열기

    - 서로 다른 숫자 세 자리라서 경우의수는 9 * 8 * 7=> 504

    - 123 ~ 987까지의 각 숫자에 대해 유효성 검사를 수행하도록 메서드를 작성한다.

    - 노드 StrikeAndBall 로 이뤄진 guess리스트에는 (숫자, 스트라이크 수, 볼 수)를 입력받는대로 add한다. 

    - guess의 원소들을 하나씩 유효성 검증을 해준다.

    - 최종적으로 검증을 마친 수들은 possibleList에 넣는다.

    - 1억 번이 1초라고 생각하면 504번 for문을 수행하는 것은 할만하기 때문에 완전 탐색을 이용할 수 있다.

 

  MySol) 240ms

<hide/>

import java.util.*;
class Node{
    int num;
    int strike;
    int ball;

    public Node(int num, int strike, int ball) {
        this.num = num;
        this.strike = strike;
        this.ball = ball;
    }
}
public class Test2 {
    
    static ArrayList<Integer> possible = new ArrayList<>();
    static  ArrayList<Node> guess = new ArrayList<>();

    public static boolean validate(int target){ 
        // 타겟 넘버와 노드의 정보가 일치하는지 확인
        // 각 노드에 대해 모두 검사한다.
        for(Node node : guess){
            if(!validCheck(target, node)){
                return false;
            }
        }
        return true;
    }

    public static boolean validCheck(int target,Node node){	
    // target과 node.num이 유효한지 확인

        int ball = 0;
        int strike = 0;

        String t = Integer.toString(target);
        String n = Integer.toString(node.num);

        for(int i = 0; i < t.length(); ++i){
            for(int j = 0;j < n.length(); ++j){
                if(t.charAt(i) == n.charAt(j) && i == j){    // 같은 자리에 같은 숫자가 있으면?
                    ++strike;
                    continue;
                }
                if(t.charAt(i) == n.charAt(j)){  // 자리가 다른 같은 글자가 있다면?
                    ++ball;
                }
            }
        }
        return  (strike == node.strike) && (ball == node.ball);
    }
    
    public static void main(String[] args) {

        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();

        for(int i = 0; i < n; ++i) {
            int num = scan.nextInt();
            int strike = scan.nextInt();
            int ball = scan.nextInt();
            guess.add(new Node(num, strike, ball));
        }
        
        for(int i = 1; i <= 9; ++i){	// 모든 세 자리 수를 넣어서 확인
            for(int j = 1; j<= 9; ++j){
                if(i == j){
                    continue;
                }
                for(int k = 1;k <= 9; ++k){
                    if(k == i || k == j){
                        continue;
                    }
                    int target = 100 * i + 10 * j + k;
                    if(validate(target)){
                        possible.add(target);
                    }
                }
            }
        }
        System.out.println(possible.size());
    }
}

    - 스터디원 코드 참고하여 작성했다. 스캐너를 쓰니까 시간이 조금 차이가 난다.

    - 처음에는 set에 가능한 후보들을 하나씩 추가해서 유효성 검증하는 방법을 생각했다.

    - 그래서 하나씩 넣어주는 방법을 고민하다가 풀이 시간이 금방 끝나 버렸다. 

    - 문제 가져온 분의 설명을 들으니 확실히 완전 탐색이 효과적이라는 것을 느꼈다.

    - target 넘버를 하나 정하고 각 노드에 대한 유효성 검증을 해서 통과할 경우 possible 리스트에 넣어줬다.

    - validate(int target) 메서드는 모든 노드와 target를 비교하면서 유효한 지 validCheck로 확인한다.

 

 

 

 


8/ 1 일요일

불참해서 내가 푼 게 없다.. 다시 꼭 풀어보자..!

 

 

3. 재귀함수가 뭔가요?

 

출처 https://www.acmicpc.net/problem/17478

 

17478번: 재귀함수가 뭔가요?

평소에 질문을 잘 받아주기로 유명한 중앙대학교의 JH 교수님은 학생들로부터 재귀함수가 무엇인지에 대하여 많은 질문을 받아왔다. 매번 질문을 잘 받아주셨던 JH 교수님이지만 그는 중앙대

www.acmicpc.net

 

  Sol) 문제 가져온 스터디원 블로그 - https://github.com/Gyubin0302

java
열기

 

 

  

4. Longest Substring Without Repeating Characters

출처 https://leetcode.com/problems/longest-substring-without-repeating-characters/

 

Longest Substring Without Repeating Characters - 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

 

  Sol) 문제 가져온 스터디원 블로그 - https://velog.io/@kormeian

<hide/>

import java.util.*;
class Solution {
    public static int lengthOfLongestSubstring(String s) {
        int i = 0;
        int j = 0;
        int maxLength = 0;
        HashSet<String> set = new HashSet<String>();

        while (i < s.length()) {
            boolean isValid = set.contains(String.valueOf(s.charAt(i)));
            if(!isValid){
                set.add(String.valueOf(s.charAt(i)));
                i++;
                maxLength = Math.max(maxLength,set.size());
            }else{
                set.remove(String.valueOf(s.charAt(j++)));
            }
        }
        return maxLength;
    }
    public static void main(String[] args)  {
        System.out.println(lengthOfLongestSubstring("pwwkew"));
    }
}