728x90

Valid Parentheses 문제

https://leetcode.com/problems/valid-parentheses/

 

Valid Parentheses - 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

Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.

An input string is valid if:

  1. Open brackets must be closed by the same type of brackets.
  2. Open brackets must be closed in the correct order.
  3. Every close bracket has a corresponding open bracket of the same type.

Example 1:

Input: s = "()"
Output: true

Example 2:

Input: s = "()[]{}"
Output: true

Example 3:

Input: s = "(]"
Output: false

풀이

백준이나 프로그래머스에서 흔히 볼 수 있는 올바른 괄호 찾기 문제와 유사합니다. Map.of를 이용해서 Map을 만들어 주었습니다. Map.of는 둘 이상의 (k, v) 쌍을 호출하게 되면 ImmutableCollections 안에 있는 MapN<K, V> 객체를 만들어 내게 됩니다. Map.of(key1, value1, key2, value2...) 이런 식으로 만든다. String으로 받은 s를 toCharArray()를 이용해서 Character로 변환해주면서 for문을 반복합니다. 만약 chr이 (, {, [ 인 여는 괄호이면 stack.push 해줍니다. 만약 stack이 비어있거나 stack.pop 했을 때 map.get(chr)인 value값과 같지 않으면 false를 return 합니다. for문이 끝나고 stack이 비어있는지 확인해 그 값을 return 한다.

 

java 9 부터 도입된 Map.of 메소드를 알아봅시다.

 java 9 버전 부터 Map.of 메소드가 생겼습니다. 이것을 언제 쓸 법 한지 알아보고, 간단하게 내부를 보도록 하겠습니다.  보시면, unmodifiable map을 리턴하게끔 되어 있습니다. 수정할 수 없는 맵을

codingdog.tistory.com


코드

class Solution {
    public boolean isValid(String s) { 
        boolean answer = true;
        Map<Character, Character> map = Map.of(')', '(', '}', '{', ']', '[');
        Stack<Character> stack = new Stack<>();
        for(Character chr : s.toCharArray()) {
            if(chr == '(' || chr == '{' || chr == '[') {
                stack.push(chr);
            }
            else if(stack.isEmpty() || stack.pop() != map.get(chr)){
                return answer = false;
            }
        }
        answer = stack.isEmpty();
        return answer;
    }
}

Merge Two Sorted Lists 문제

https://leetcode.com/problems/merge-two-sorted-lists/

 

Merge Two Sorted Lists - 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

You are given the heads of two sorted linked lists list1 and list2.

Merge the two lists in a one sorted list. The list should be made by splicing together the nodes of the first two lists.

Return the head of the merged linked list.

Example 1:

스크린샷 2022-09-30 오후 7 56 10

Input: list1 = [1,2,4], list2 = [1,3,4]
Output: [1,1,2,3,4,4]

Example 2:

Input: list1 = [], list2 = []
Output: []

Example 3:

Input: list1 = [], list2 = [0]
Output: [0]

Constraints:

  • The number of nodes in both lists is in the range [0, 50].
  • -100 <= Node.val <= 100
  • Both list1 and list2 are sorted in non-decreasing order.

풀이

LeetCode에서 알고리즘 문제를 풀다 보면 ListNode를 이용해 풀어야 하는 문제가 있습니다. ListNode로 list1, list2를 받아서 p1, p2에 각각 넣어줍니다. while을 이용해서 p1과 p2가 null이 아닐 때까지 반복하는데 만약 p1의 값이 p2의 값과 비교했을 때 p2의 값이 크면 p.next에 p1을 대입한다. p1의 값을 p1.next의 값으로 바꾸어주고 p에 p.next 값을 대입한다. 만약 p1의 값이 더 클 경우 p.next에 p2의 값을 대입한다. p2.next 값을 p2에 대입하고 p에 p.next값을 대입한다. while 문이 끝나고도 남은 ListNode가 발생할 수 있어 p1이 null이 아니면 p.next에 p1을 대입하고 p2가 null이 아니면 p.next에 p2를 대입한다.

 

[LeetCode] 자주 사용되는 자료구조 - ListNode 구현

모든 소스 코드는 여기 있습니다. LeetCode 에서 알고리즘 문제를 풀다보면 ListNode 를 이용해 테스트 해야할 일이 많이 있습니다. 테스트 코드나 main 메서드 내에서 객체를 생성하고 ListNode 를 파라

jaime-note.tistory.com


코드

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode head = new ListNode();
        ListNode p = head;

        ListNode p1 = list1;
        ListNode p2 = list2;

        while(p1 != null && p2 != null) {
            if(p1.val < p2.val) {
                p.next = p1;
                p1 = p1.next;
            }
            else {
                p.next = p2;
                p2 = p2.next;
            }
            p = p.next;
        }
        if(p1 != null) {
            p.next = p1;
        }
        if(p2 != null) {
            p.next = p2;
        }
        return head.next;
    }
}
728x90

'알고리즘 > 알고리즘 문제풀이' 카테고리의 다른 글

프로그래머스 최솟값 만들기, JadenCase 문자열 만들기  (0) 2022.09.23
백준) DP, DFS  (0) 2022.08.27
백준) HashMap  (0) 2022.07.23
백준) BFS, 다익스트라  (0) 2022.07.19
백준) 우선순위 큐, DP  (0) 2022.07.18
728x90

최솟값 만들기

https://school.programmers.co.kr/learn/courses/30/lessons/12941

스크린샷 2022-09-22 오후 5 55 22


문제 설명

길이가 같은 배열 A, B 두개가 있습니다. 각 배열은 자연수로 이루어져 있습니다.
배열 A, B에서 각각 한 개의 숫자를 뽑아 두 수를 곱합니다. 이러한 과정을 배열의 길이만큼 반복하며, 두 수를 곱한 값을 누적하여 더합니다. 이때 최종적으로 누적된 값이 최소가 되도록 만드는 것이 목표입니다. (단, 각 배열에서 k번째 숫자를 뽑았다면 다음에 k번째 숫자는 다시 뽑을 수 없습니다.)

예를 들어 A = [1, 4, 2] , B = [5, 4, 4] 라면

  • A에서 첫번째첫 번째 숫자인 1, B에서 첫 번째 숫자인 5를 뽑아 곱하여 더합니다. (누적된 값 : 0 + 5(1x5) = 5)
  • A에서 두번째 숫자인 4, B에서 세 번째 숫자인 4를 뽑아 곱하여 더합니다. (누적된 값 : 5 + 16(4x4) = 21)
  • A에서 세번째 숫자인 2, B에서 두 번째 숫자인 4를 뽑아 곱하여 더합니다. (누적된 값 : 21 + 8(2x4) = 29)

즉, 이 경우가 최소가 되므로 29를 return 합니다.

배열 A, B가 주어질 때 최종적으로 누적된 최솟값을 return 하는 solution 함수를 완성해 주세요.


제한사항

  • 배열 A, B의 크기 : 1,000 이하의 자연수
  • 배열 A, B의 원소의 크기 : 1,000 이하의 자연수

입출력 예

A B answer
[1, 4, 2] [5, 4, 4] 29
[1,2] [3,4] 10

풀이

길이가 같은 두개의 배열이 주어지고 두 배열의 원소를 서로 곱해서 answer이라는 변수에 누적 저장해서 answer 값이 최소가 되는 값을 구하면 되는 문제이다. A, B를 오름차순으로 정렬하면 A는 1, 2, 4가 되고 B는 4, 4, 5가 된다. A에서 오름차순으로 선택하면 1 B에서 큰 수부터 선택하면 5 두 수를 곱해주면 0 + ( 1 * 5 ) = 5 -> 5 + ( 2 * 4) = 13 -> 13 + (4 * 4) = 29가 된다.


코드

import java.util.*;
class Solution
{
    public int solution(int []A, int []B)
    {
        int answer = 0;
        Arrays.sort(A);  // 두 배열을 정렬 해준다.
        Arrays.sort(B);

        for(int i = 0; i < A.length; i++) {
            answer = answer + (A[i] * B[A.length - 1 - i]);  // a는 오름차순으로 선택하고 b는 큰 수 부터 선택헤서 곱해준다.
        }
        return answer;
    }
}

JadenCase 문자열 만들기

(문제 설명 혹은 링크)
https://school.programmers.co.kr/learn/courses/30/lessons/12951

스크린샷 2022-09-23 오후 4 28 38


문제 설명

JadenCase란 모든 단어의 첫 문자가 대문자이고, 그 외의 알파벳은 소문자인 문자열입니다. 단, 첫 문자가 알파벳이 아닐 때에는 이어지는 알파벳은 소문자로 쓰면 됩니다. (첫 번째 입출력 예 참고)
문자열 s가 주어졌을 때, s를 JadenCase로 바꾼 문자열을 리턴하는 함수, solution을 완성해주세요.


제한 조건

  • s는 길이 1 이상 200 이하인 문자열입니다.
  • s는 알파벳과 숫자, 공백문자(" ")로 이루어져 있습니다.
    • 숫자는 단어의 첫 문자로만 나옵니다.
    • 숫자로만 이루어진 단어는 없습니다.
    • 공백 문자가 연속해서 나올 수 있습니다.

입출력 예

s return
"3people unFollowed me" "3people Unfollowed Me"
"for the last week" "For The Last Week"

풀이

이 문제를 봤을 때 비교적 간단한 문제라고 생각하고 풀었습니다. 하지만 문제를 제대로 읽지 않은 탓에 엄청 헤맸습니다. 우선 공백 문자를 보자마자 String []str = s.split(" "); 으로 잘랐습니다. 잘못된 풀이로 풀었을 때 substring(0, 1)을 이용해서 첫 번째 문자를 구하고 toUpperCase()를 이용해 첫 번째 문자를 대문자로 변환해 주었습니다. 또한 substring(1, str[i].length()).toLowerCase()를 이용해서 첫 번째 문자를 제외하고 변환하여 더하였습니다. 하지만 answer를 더해주는 과정에서 마지막 문자열에 공백 문자가 포함됩니다. 따라서 원래 문자열 마지막이 공백일 경우와 아닐 경우에 대한 코드를 작성하였습니다. 하지만 제한 조건에 공백 문자가 연속해서 나올 수 있다는 것을 보고 다시 문제를 풀었습니다. 모든 문자열 소문자로 변경하고 첫 번째 글자인지 판단하는 boolean 변수를 추가해 주었습니다. 문자열만큼 반복해서 for문을 수행하고 만약 공백이 나오면 isFirst를 true로 변경하고 아니면 false를 수행한다. 만약 isFirst가 true일 경우 대문자로 변경한다.


잘못된 코드

public class JadenCase {
    public static void main(String[] args) {
        String s = "for the last week ";
        String []str = s.split(" "); // 공백을 기준으로 문자열 자르기
        String answer = "";

        // 공백을 기준으로 잘려진 문자열의 수만큼 반복
        for(int i = 0; i < str.length; i++) {
            if(str.length == 0) {
                answer += " ";
            }
            else {
                answer += str[i].substring(0, 1).toUpperCase(); // 단어 첫번째 대문자로 변환하여 더하기
                answer += str[i].substring(1, str[i].length()).toLowerCase(); // 첫글자를 제외하고 소문자로 변환하여 더하기
                answer += " "; // 띄어쓰기
            }
        }
        //원래 문자열 마지막이 공백일 경우 그대로 answer 반환
                if(s.substring(s.length() -1, s.length()).equals(" ")) {
               System.out.println(answer);
                }
                //마지막에 공백이 더해져서 그 공백을 제외한 answer값 반환
                else {
              answer = answer.substring(0, answer.length() - 1);
              System.out.println(answer);
                }
    }
}

정확한 코드

class Solution {
    public String solution(String s) {
        String answer = "";
         // 모든 문자열 소문자로 변경
        String[] srr = s.toLowerCase().split("");

        boolean isFirst = true; // 첫번째 글자인지 판단 
        // 문자열 만큼 반복
        for(int i = 0; i < srr.length; i++) {
            // 첫 글자일 경우 대문자로 변경
            if(isFirst) {
                answer += srr[i].toUpperCase(); 
            }
            else {
                answer += srr[i];
            }
            // 공백이 나오면 첫 글자 true로 변경
            if(srr[i].equals(" ")) {
                isFirst = true;
            }
            else {
                isFirst = false;
            } 
        }
        return answer;
    }
}

 

728x90

'알고리즘 > 알고리즘 문제풀이' 카테고리의 다른 글

LeetCode Valid Parentheses, Merge Two Sorted Lists  (0) 2022.10.03
백준) DP, DFS  (0) 2022.08.27
백준) HashMap  (0) 2022.07.23
백준) BFS, 다익스트라  (0) 2022.07.19
백준) 우선순위 큐, DP  (0) 2022.07.18
728x90

수익 4097번


내가 떠올린 풀이 해설

입력이 많지 않아 BufferedReader보단 Scanner를 사용했습니다. 처음 코드를 작성했을 때 max 값을 0으로 선언을 해주었지만 입력값이 음수일 경우 max 값을 구할 때 max 값이 0이 되므로 max 값을 Integer.MIN_VALUE로 선언해 주어야 합니다. 총수입을 담을 sum 변수를 만들었습니다. 입력의 마지막은 0으로 구분해서 입력 n이 0이면 break 하고 0이 아니면 for 문으로 n 미만까지 for 문을 수행한다. for 문에는 입력 값을 담을 num을 선언해 주었고 입력받은 값을 sum에 누적해서 더합니다. Math.max를 이용해 max와 sum을 비교해 큰 값을 max에 담았습니다. sum의 값이 음수가 되면 sum 값을 0으로 다시 초기화하였습니다.


정확한 풀이

import java.util.*;
public class Baek4097 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(true) {
			int n = sc.nextInt();
			int max = Integer.MIN_VALUE; 
			int sum = 0;
			if(n == 0) {
				break;
			}
			else {
				for(int i = 0; i < n; i++) {
					int num = sc.nextInt();
					sum += num;                // -3, 1, 10, 8, 3, 11
					max = Math.max(max, sum);  // 0, 1, 10, 10, 10, 11
					if(sum < 0) {
						sum = 0;
					}
				}
				System.out.println(max);
			}
		}
	}
}

풀이 2

문제 분류가 다이나믹 프로그래밍이어서 DP로 풀어보려 했는데 방법이 떠오르지 않아 DP를 이용해서 푼 풀이를 가져왔습니다. 위의 코드와 차이점은 배열을 이용해서 현재 i의 값과 직전 값과 현재 i의 값을 더한 게 더 클 때 arr[i]의 값을 직전 값과 현재 i의 값으로 바꿔주는 것입니다. DP의 메모리제이션을 이용해서 해결한 것 같습니다.
https://velog.io/@pss407/%EB%B0%B1%EC%A4%804097-%EC%88%98%EC%9D%B5

 

[백준]#4097 수익

문제연종이는 창업했다. 오늘은 창업한지 N일이 되었고, 매일 매일 수익을 적어놓았다.어느 날 연종이는 가장 많이 돈을 번 구간이 언제인지 궁금해졌다.오늘이 창업한지 6일 되었고, 수익이 다

velog.io


정확한 풀이

import java.util.*;

public class Baek4097 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(true) {
			int n = sc.nextInt();
			int max = Integer.MIN_VALUE;
			int sum = 0;
			int[] arr = new int[n];
			if(n == 0) {
				break;
			}
			else {
				for(int i = 0; i < n; i++) {
				        int x = sc.nextInt();
	                                arr[i] = x;
                                        if(i > 0) {
	                                       int y = arr[i-1];
                                               if(x + y > x) {   //직전 값과 현재 i의 값을 더한게 더 클 때
	                                          arr[i] = x + y;
                                               }
	                                 }
	                         }
	                         max = Math.max(max, arr[i]);
			}
			System.out.println(max);
		}
	}
}

단지 번호 붙이기 2667번


내가 떠올린 풀이 해설

상하좌우를 탐색할 int 배열 dx, dy를 선언합니다. 지도 크기를 입력받을 n, 2차원 배열의 map, DFS의 visit 배열, 총 단지 수를 구하기 위한 total, 각 단지에 속하는 집의 수를 구하기 위해 cnt를 선언해 주었습니다. BufferedReader를 이용해 입력을 받았습니다. map의 입력은 split를 이용해 잘라서 map의 2차원 배열에 넣어 주었습니다.(split("")[i]의 참고 자료: https://crazykim2.tistory.com/549) 전체 map을 탐색하기 위해 이중 for 문을 이용하였고 map의 (i, j)가 1이고 방문하지 않았다면 총 단지 수와 cnt의 수를 늘려주고 DFS를 호출합니다. DFS에서는 상하좌우 탐색을 진행하면서 cnt를 늘려줍니다. 마지막으로 cnt의 값을 List에 담아줍니다. 각 단지 내 집의 수를 오름차순으로 정렬하여 출력해 주어야 하므로 Collections.sort()를 이용해 정렬하였습니다.


정확한 풀이

import java.util.*;
import java.io.*;
public class Baek2667 {
	static int[] dx = {1, 0 ,0, -1};
	static int[] dy = {0, 1, -1, 0};
	static int n; // 지도 크기 
	static int[][] map;
	static boolean[][] visit;
	static int total = 0;  // 총 단지 수 
	static int cnt;
	static List<Integer> cnts = new ArrayList<>(); // 각 단지에 속하는 집의 수 
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		n = Integer.parseInt(br.readLine());
		map = new int[n][n];
		visit = new boolean[n][n];
		
		String str;
		for(int i = 0; i < n; i++) {
			str = br.readLine();
			for(int j = 0; j < n; j++) {
				map[i][j] = Integer.parseInt(str.split("")[j]);
			}
		}
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < n; j++) {
				cnt = 0;
				if(map[i][j] == 1 && !visit[i][j]) {
					total++;
					cnt++;
					dfs(i, j);
					cnts.add(cnt);
				}
			}
		}
		System.out.println(total);
		Collections.sort(cnts);
		for(int i = 0; i < cnts.size(); i++) {
			System.out.println(cnts.get(i));
		}
	}

	private static void dfs(int i, int j) {
		visit[i][j] = true;
		for(int k = 0; k < 4; k++) {
			int nx = dx[k] + i;
			int ny = dy[k] + j;
			if(nx >= 0 && nx < n && ny >= 0 && ny < n) {
				if(!visit[nx][ny] && map[nx][ny] == 1) {
					cnt++;
					dfs(nx, ny);
				}
			}
		}
	}
}

오늘의 회고

요즘 스터디와 공모전으로 너무 바빠서 코딩 테스트 문제를 풀지 못했더니 많이 까먹은 것 같습니다. 이제 곧 하반기 채용 시작인데 다시 코딩 테스트 공부를 좀 해야겠습니다. 알고리즘 너무 어려워 이번에 알고리즘 스터디에 참여하게 되었는데 다들 실력이 좋으셔서 놀랐습니다. 분발하자

728x90
728x90

9375번 패션왕 신해빈


내가 떠올린 풀이 해설

프로그래머스 위장 문제와 동일한 문제여서 어렵지 않게 해결할 수 있었습니다. HashMap을 이용해서 의상 종류를 key값으로 넣고 value값은 숫자로 넣습니다. 만약 같은 키가 있으면 숫자를 1 늘려줍니다. 정해진 value값으로 경우의 수를 이용해서 풀었습니다.


정확한 풀이

mport java.util.*;
import java.io.*;

public class Baek9375 {

	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		int n = Integer.parseInt(br.readLine());
		int answer = 1;
		for(int i = 0; i < n; i++) {
			HashMap<String, Integer> hash = new HashMap<>();
			answer = 1;
			int m = Integer.parseInt(br.readLine());
			for(int j = 0; j < m; j++) {
				StringTokenizer st = new StringTokenizer(br.readLine());
				String clo = st.nextToken();
				String qwe = st.nextToken();
				hash.put(qwe, hash.getOrDefault(qwe, 0) + 1);
			}
			Set<String> keySet = hash.keySet();
			for(String key : keySet) {
				answer *= hash.get(key) + 1;
			}
			System.out.println(answer - 1);
		}
	}

}
728x90
728x90

step 2 - 4. 정수 삼각형


내가 떠올린 풀이 해설

  1. DP 삼각형의 가장 왼쪽의 값 (DP[i][0])은 한 줄 위의 가장 왼쪽 값(DP[i - 1][0])에 현재 값(triangle[i][0])을 더한 값이 된다.
    DP[i][0] = DP[i-1][0] + triangle[i][0]이 됩니다.
  2. 삼각형의 가장 오른쪽의 값 (DP[i][i])은 한 줄 위의 가장 오른쪽 값(DP[i-1][i-1])에 현재 값(triangle[i][i])을 더한 값이 된다.
    DP[i][i] = DP[i-1][i-1] + triangle[i][i]이 됩니다.
  3. 삼각형의 1번과 2번을 제외한 나머지는 한줄 위의 오른쪽 값과 왼쪽 값 중 큰 값에 현재 값을 더한 값이 된다.
    DP[i][i] = Max(DP[i - 1][j - 1], DP[i - 1][j]) + triangle[i][j]가 됩니다.
  4. DP 배열에서 max 값을 출력하기 위해 answer = Math.max(answer, dp[i][j])을 해준다.

정확한 풀이

public class step2_4 {

	public static void main(String[] args) {
		int[][] tri = {{7},
				{3, 8},
				{8, 1, 0},
				{2, 7, 4, 4},
				{4, 5, 2, 6, 5}};
		int [][]dp = new int[tri.length][tri[tri.length - 1].length];
		int answer = 0;
		int max = 0;
		dp[0][0] = tri[0][0];
		for(int i = 1; i < tri.length; i++) {
			dp[i][0] = dp[i - 1][0] + tri[i][0];
			dp[i][i] = dp[i - 1][i - 1] + tri[i][i];
			for(int j = 1; j <= i - 1; j++) {
				dp[i][j] = Math.max(dp[i - 1][j - 1], dp[i - 1][j]) + tri[i][j];
				answer = Math.max(answer, dp[i][j]);
			}
		}
		System.out.println(answer);
	}
}

오늘의 회고

오늘은 DP문제와 프로그래머스 위장 문제와 유사한 문제를 백준에서 찾아서 HashMap 문제를 풀었습니다. 점화식은 도출을 해냈지만 DP 배열을 만들 생각을 하지 못하고 triangle 배열에서 점화식을 처리해주려고 했는데 생각처럼 되지 않았습니다. HashMap문제는 거의 동일해서 어렵지 않게 해결할 수 있었습니다. 알고리즘 고수가 되고 싶습니다.ㅠㅠ

728x90
728x90

step 2 - 3. 올바른 괄호의 개수


내가 떠올린 풀이 해설

괄호를 보고 stack을 이용해서 풀려고 했는데 괄호 문자를 입력으로 주지 않아 DFS의 성질을 이용해 풀었다. 올바른 괄호의 짝 중에, '('로 시작했으면 ')'로 끝나는 성질을 이용해 ')'의 개수가 '('보다 많으면 올바르지 않은 식으로 간주하고, 이 모든 경우의 수를 dfs로 찾았다.

https://tosuccess.tistory.com/173

 

[프로그래머스 level_4] 올바른 괄호의 갯수 for JAVA

programmers.co.kr/learn/courses/30/lessons/12929 코딩테스트 연습 - 올바른 괄호의 갯수 올바른 괄호란 (())나 ()와 같이 올바르게 모두 닫힌 괄호를 의미합니다. )(나 ())() 와 같은 괄호는 올바르지 않은 괄..

tosuccess.tistory.com


정확한 풀이

import java.util.*;
public class step2_3 {
	static int answer;
	public static void main(String[] args) {
		int n = 2;
		answer = 0;
		DFS(0, 0, n);
		System.out.println(answer);
	}
	private static void DFS(int left, int right, int n) {
		if(left < right) {
			return;
		}
		if(left == n && right == n) {
			answer++;
			return;
		}
		if(left > n || right > n) {
			return;
		}
		DFS(left + 1, right, n);
		DFS(left, right + 1, n);
	}
}

오늘의 회고

오늘은 프로그래머스 3주 차 문제를 풀었습니다. DFS를 이용해서 푸는 문제였다. DFS 문제라고 떠올리기는 했지만 문제를 해결하는 방법의 아이디어가 떠오르지 않았다... 좀 더 넓은 방식으로 문제를 해결해야 되는데 어떻게 공부해야 될지 잘 모르겠다.ㅠㅠ

728x90
728x90

step 2 - 2. 게임 맵 최단거리


내가 떠올린 풀이 해설

DFS로 풀어도 답이 나오는 문제인데 저는 BFS로 풀었습니다. dx, dy로 상하좌우를 탐색할 배열을 만들어 준다. 또한 visit 배열을 만들어준다. visit배열은 BFS를 탐색하면서 거리가 1씩 늘어날수록 이동한 거리를 담아 줄 배열이다. 만약 answer가 0이면 -1, 아니면 answer를 리턴해준다. BFS 메서드에서는 BFS를 이용할 Queue를 생성하고 시작점인 0,0을 배열로 Queue에 add 해준다. Queue가 빌 때까지 반복한다. for문으로 상하좌우를 탐색하면서 만약 nx, ny가 0보다 같거나 크고, nx, ny가 map길이보다 작아야 하고, maps배열의 nx, ny위치가 1이고, visit배열의 nx, ny가 0이면 visit [nx][ny]에 visit [x][y] + 1 값을 넣어준다. 그리고 Queue에 nx, ny를 add 해준다.


정확한 풀이

import java.util.*;
public class step2_2 {
    static int[] dx = {1, 0, -1, 0};
    static int[] dy = {0, -1, 0, 1};
    static int answer;
    static int[][] visit;
	public static void main(String[] args) {
		int [][]maps = {{1, 0, 1, 1, 1},
				{1, 0, 1, 0, 1},
				{1, 0, 1, 1, 1},
				{1, 1, 1, 0, 1,},
				{0, 0, 0, 0, 1}};
		answer = 0;
		int [][] visit = new int[maps.length][maps[0].length];
		visit[0][0] = 1;
		BFS(maps, visit);  
		answer = visit[maps.length - 1][maps[0].length - 1];
		if(answer == 0) {
			System.out.println(-1);
		}
		System.out.println(answer);
	}
	private static void BFS(int[][] maps, int[][] visit) {
		Queue<int[]> que = new LinkedList<>();
		que.add(new int[] {0, 0});
		while(!que.isEmpty()) {
			int[] now = que.poll();
			int x = now[0];
			int y = now[1];
			for(int i = 0; i < 4; i++) {
				int nx = dx[i] + x;
				int ny = dy[i] + y;
				if(nx >= 0 && nx < maps.length && ny >= 0 && ny < maps[0].length && maps[nx][ny] == 1 && visit[nx][ny] == 0) {
					visit[nx][ny] = visit[x][y] + 1;
					que.add(new int[] {nx, ny});
				}
			}
		}
    }
}

오늘의 회고

요즘 계속 알고리즘 문제를 1문제밖에 풀지 못하네요. 알고리즘 고수가 되는 그날까지 분발하겠습니다. 

728x90
728x90

step 2 - 1. 위장


내가 떠올린 풀이 해설

문제를 읽다 보면 hashMap으로 풀어야 하는 단서가 되는 게 있다. 제한 사항에 같은 이름을 가진 의상은 존재하지 않습니다를 보고 떠올릴 수 있을 것 같다. 저는 hashMap의 key에 의상의 이름을 담고, value에 종류를 담아서 풀려고 했다. 하지만 key에 종류를 담고 value에 숫자를 담는다. 만약 담으려는 키가 존재하면 key의 value값을 리턴하고 만약 존재하지 않으면 default값을 반환하는 getOrDefault를 이용했다. 같은 종류의 의상은 1개밖에 입지 못하므로 경우의 수를 이용해서 풀었다. 


정확한 풀이

import java.util.*;

public class step2_1 {

	public static void main(String[] args) {
		String[][] clothes = {{"yellowhat", "headgear"}, 
								{"blue", "eyewear"}, 
								{"green_turban", "headgear"}};
		HashMap<String, Integer> map = new HashMap<>();
		int answer = 1;
		for(int i = 0; i < clothes.length; i++) {
			map.put(clothes[i][1], map.getOrDefault(clothes[i][1], 0) + 1);
        }
		Set<String> keySet = map.keySet();
		for(String key : keySet) {
			answer *= map.get(key) + 1;
		}
		System.out.println(answer - 1);
	}
}

오늘의 회고

문제를 풀면 풀수록 부족하다는 생각이 드네요. 언제쯤 쉽게 문제를 해결할 수 있을까요...? 오늘은 맥북 충전 단자가 고장이나서 서비스 센터에 갔다 오느라 정신없었던 하루였습니다. 공부도 많이 못했습니다. 남은 시간이라도 열심히 공부하겠습니다.

728x90

+ Recent posts