Dijkstra 선형 탐색 : https://champcoder.tistory.com/8

 

[알고리즘] Dijkstra-1

선형 탐색을 이용한 풀이 public class Dijkstra { public static int n = 6; public static int INF = 1000000; public static int[][] arr = {{0, 2, 5, 1, INF, INF}, {2, 0, 3, 2, INF, INF}, {5, 3, 0, 3, 1, 5}, {1, 2, 3, 0, 1, INF}, {INF, INF, 1, 1, 0, 2

champcoder.tistory.com

Dijkstra 우선순위 큐 활용 : https://champcoder.tistory.com/71

 

[알고리즘] Dijkstra-2

우선순위 큐를 이용한 풀이 import java.util.ArrayList; import java.util.HashMap; import java.util.PriorityQueue; public class DijkstraByPriorityQueue { public static int n = 6; // 노드의 개수 public static int INF = 1000000; // 무한대를

champcoder.tistory.com

Dijkstra(다익스트라) 알고리즘 문제 풀이 Java 소스 코드

선형 탐색 & 우선순위 큐 활용

선형 탐색 풀이에서 반복횟수를 n-2로 해도 되는 이유

'알고리즘 > Dijkstra' 카테고리의 다른 글

[알고리즘] Dijkstra-2  (0) 2022.09.07
[알고리즘] Dijkstra-1  (0) 2022.08.31

[Java] PCCP 모의고사 1회 외톨이 알파벳 : https://champcoder.tistory.com/80

 

[Java] PCCP 모의고사 1회 외톨이 알파벳

import java.util.*; public class PccpTest1_1 { // PCCP 모의고사 1회 1번 외톨이 알파벳 public static String solution(String input_string) { String answer = ""; char tempChar; int tempCnt = 0; int repeatCnt = 0; Queue q = new LinkedList(); HashMa

champcoder.tistory.com

[Java] PCCP 모의고사 1회 체육대회 : https://champcoder.tistory.com/84

 

[Java] PCCP 모의고사 1회 체육대회

public class PccpTest1_2 { // PCCP 모의고사 1회 2번 체육대회 public static int[][] studentAbility; public static int studentCnt = 0; public static int sportsCnt = 0; public static int[] exceptCmbMax; public static int getMaxAbility(int studentCmb

champcoder.tistory.com

[Java] PCCP 모의고사 1회 유전법칙 : https://champcoder.tistory.com/86

 

[Java] PCCP 모의고사 1회 유전법칙

public class PccpTest1_3 { // PCCP 모의고사 1회 3번 유전법칙 public static String solve(int generation, long number) { long upperCaseLastNum = 0; long centerGroupLastNum = 0; String strRoot = "Rr"; long tempNum = 0; if (generation == 1) { return

champcoder.tistory.com

[Java] PCCP 모의고사 1회 운영체제 : https://champcoder.tistory.com/91

 

[Java] PCCP 모의고사 1회 운영체제

import java.util.PriorityQueue; public class PccpTest1_4 { // PCCP 모의고사 1회 4번 운영체제 public static long[] solution(int[][] program) { long[] answer = {}; long callTime = 0; // OS 호출 시각 int runningTime = 0; // OS 수행 시간 long

champcoder.tistory.com

프로그래머스 PCCP 모의고사 문제 풀이 Java 소스 코드

import java.util.HashMap;

public class Solution {
	
	// 모음사전
	
	public static int solution(String word) {
		int answer = 0;
		
		HashMap<Character, Integer> hm = new HashMap<>();
		
		hm.put('A', 0);
		hm.put('E', 1);
		hm.put('I', 2);
		hm.put('O', 3);
		hm.put('U', 4);
		
		// A     1
		// AA    2
		// AAA   3
		// AAAA  4
		// AAAAA 5
		// AAAAE 6   (AAAAA보다 + 1) (+ 1)
		// ...
		// AAAAU 9
		// AAAE  10  (AAAA보다 + 6) (1 + 5)
		// AAAEA 11
		// AAAEU 15
		// AAAI  16
		// ...
		// AAAO  22
		// ...
		// AAAU  28
		// AAAUA 29
		// ...
		// AAAUU 33
		// AAE   34  (AAA보다 + 31) (1 + 5 + 25)
		// AAEA  35
		// AAEAA 36
		// ...
		// AAI   65
		// ...
		// AE    158 (AA보다 + 156) (1 + 5 + 25 + 125)
		// ...
		// AI    314
		// ...
		// E     782 (A보다 + 781) (1 + 5 + 25 + 125 + 625)
		// 첫 번째 자리 문자 하나가 바뀌기 위해서는 + 781(1 + 5 + 25 + 125 + 625)이 필요
		// 두 번째 자리 문자 하나가 바뀌기 위해서는 + 156(1 + 5 + 25 + 125)이 필요
		
		int[] arr = {781, 156, 31, 6, 1};
		
		answer += word.length(); // word 길이만큼 증가
		
		for (int i = 0; i < word.length(); i++) {
			answer += hm.get(word.charAt(i)) * arr[i]; // 바뀐 문자 체크하여 증가
		}
		
		return answer;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String word = "AAAAE";
		
		System.out.println(solution(word)); // 6
	}
}

프로그래머스 모음사전 문제 풀이 Java 소스 코드

public class Solution {
	
	// 정수 삼각형
	
	public static int solution(int[][] triangle) {
		int answer = 0;
		
		int[][] dpTriangle = new int[triangle.length][triangle.length];
		
		dpTriangle[0][0] = triangle[0][0];
		
		for (int i = 1; i < triangle.length; i++) {
			
			// 가장 왼쪽
			dpTriangle[i][0] = dpTriangle[i - 1][0] + triangle[i][0];
			
			// 나머지
			for (int j = 1; j < i; j++) {
				dpTriangle[i][j] = Math.max(dpTriangle[i - 1][j - 1], dpTriangle[i - 1][j]) + triangle[i][j];
			}
			
			// 가장 오른쪽
			dpTriangle[i][i] = dpTriangle[i - 1][i - 1] + triangle[i][i];
		}
		
		for (int i = 0; i < triangle.length; i++) {
			answer = Math.max(answer, dpTriangle[triangle.length - 1][i]);
		}
		
		return answer;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[][] triangle = {{7}, {3, 8}, {8, 1, 0}, {2, 7, 4, 4}, {4, 5, 2, 6, 5}};
		
		System.out.println(solution(triangle));
	}
}

프로그래머스 정수 삼각형 문제 풀이 Java 소스 코드

Brute Force(완전 탐색)

단순히 힘만으로 풀겠다는 알고리즘을 의미한다.

즉, 모든 것을 다 해보겠다는 의미이며,

숫자 4자리 비밀번호를 풀어야 하는 경우 0000부터 9999까지 모두 대입하는 것을 예로 들 수 있다.

Brute Force 풀이 방법

1. for / while loop 활용(간단한 문제의 경우)

2. 재귀함수 활용(복잡한 문제의 경우)

'알고리즘 > Brute Force' 카테고리의 다른 글

[알고리즘] Brute Force-1  (0) 2022.11.09

<재귀함수를 활용한 소수 만들기 완전 탐색>

import java.util.HashSet;
import java.util.Iterator;

public class CreatePrimeNumber {
	
	// 소수 만들기
	
	static HashSet<Integer> hs = new HashSet<>();
	
	public static boolean isPrimeNumber(int num) {
		
		int limit = 0;
		
		if (num == 0 || num == 1) { // 0과 1은 소수가 아니다.
			return false;
		}
		
		limit = (int) Math.sqrt(num);
		
		for (int i = 2; i <= limit; i++) { // num이 80이라면 루트 80의 정수 값인 8까지만 체크하여 나누어떨어지는지 확인하면 된다.
			
			if (num % i == 0) { // 나누어떨어진다면 num은 1과 자기 자신을 제외한 약수를 가지는 것이므로 소수가 아니다.
				return false;
			}
		}
		
		return true;
	}
	
	public static void recursive(String comb, String rest) {
		
		if (!"".equals(comb)) {
			hs.add(Integer.parseInt(comb)); // HashSet은 중복을 허용하지 않는다.
		}
		
		for (int i = 0; i < rest.length(); i++) { // rest 문자열 중 한 문자를 comb에 붙이고, 그 문자를 제외한 나머지 문자열을 rest 값으로 다시 재귀함수를 호출한다.
			recursive(comb + rest.charAt(i), rest.substring(0, i) + rest.substring(i + 1));
		}
	}
	
	public static int solution(String numbers) {
		int answer = 0;
		int tempNum = 0;
		
		// STEP 1. 모든 조합의 숫자를 만든다.
		recursive("", numbers); // 재귀함수 호출("", "011")
		
		// STEP 2. 소수의 개수를 센다.
		Iterator<Integer> it = hs.iterator();
		
		while (it.hasNext()) {
			tempNum = it.next();
			
			if (isPrimeNumber(tempNum)) { // 소수이면
				answer++; // 개수 1 증가
			}
		}
		
		// STEP 3. 소수의 개수를 리턴한다.
		return answer;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String numbers = "011"; // 11, 101
		
		System.out.println(solution(numbers)); // 2
	}
}

<반복문을 활용한 소수 찾기 완전 탐색>

import java.util.Arrays;

public class Solution {
	
	// 소수 찾기
	
	public static int solution(int n) {
        int answer = 0;
        
        boolean[] boolArr = new boolean[n + 1]; // 0 ~ n까지 체크를 위함
        
        Arrays.fill(boolArr, true);
        
        boolArr[0] = false;
        boolArr[1] = false;
        
        for (int i = 2; i <= Math.sqrt(n); i++) { // n이 10이라면 루트 10의 정수 값인 3까지 체크
        	
        	if (boolArr[i] == true) { // false 처리가 되지 않은 값이라면
        		int j = 2;
        		
        		while (i * j <= n) {
        			boolArr[i * j] = false;
            		j++;
            	}
        	}
        }
        
        for (int i = 0; i < boolArr.length; i++) {
        	
        	if (boolArr[i] == true) {
        		answer++;
        	}
        }
        
        return answer;
    }

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int n = 10;
		
		System.out.println(solution(n)); // 4개 // 2, 3, 5, 7
	}
}

Brute Force 알고리즘 문제 풀이 Java 소스 코드

'알고리즘 > Brute Force' 카테고리의 다른 글

[알고리즘] Brute Force 이해하기  (0) 2022.11.09

DFS : 한 드라마를 몰아서 본다(Stack이나 재귀함수를 사용)

BFS : 여러 드라마를 한 편씩 본다.(Queue나 LinkedList를 사용)

 

DFS  또는 BFS로 풀어야 하는 대표적인 유형

1. 경로 탐색 유형(최단거리, 시간)
2. 네트워크 유형(연결)
3. 조합 유형(모든 조합 만들기)

 

DFS가 동작 검증이 쉽다.

하나씩 조합을 만들어서 정답과 비교하기 때문에 조합이 잘 나왔는지 확인이 쉽다.

하지만 수행 시간 관점에서는 복불복

운이 좋으면 첫 번째 조합이 최적의 답, 최악의 경우에는 모든 조합을 다 만들어 보면서 시간을 낭비하게 된다.

 

BFS는 한 번에 여러 조합들을 한 칸 한 칸씩 만들다 보니 조합이 완성되어 정답과 비교하는 시점에
언제 이렇게 만들어졌는지 또는 어디서부터 틀린 건지 분석하기가 까다롭다.

초반에는 느려 보일 수 있지만 하나의 정답만 찾고 나면 나머지 경우의 수는 정답에서 제외된다.

가장 먼저 넣었던 것을 꺼내기 => 연결된 점을 Queue에 넣기 => Queue가 비워질 때까지 반복

 

코딩 테스트에서 앞에 출제된 문제는 DFS로, 뒤에 출제된 문제는 탐색 시간이 오래 걸릴 거 같다면 BFS로 푸는 것을 추천한다.

'알고리즘 > DFS & BFS' 카테고리의 다른 글

[알고리즘] BFS-2  (0) 2022.11.26
[알고리즘] DFS-2  (0) 2022.11.26
[알고리즘] BFS-1  (0) 2022.08.31
[알고리즘] DFS-1  (0) 2022.08.31

DP(Dynamic Programming)는 완전 탐색, DFS, BFS와 같이 수많은 경우를 따져봐야 할 때

속도가 느려지는 문제를 개선하고자 수행 시간 단축을 목적으로 만들어진 알고리즘이다.

프로그래머스의 정수 삼각형 문제를 예로 들어보자

DP 삼각형의 11이 16으로 갱신되었으므로 이제 11을 만들었던 7-3-1 조합은 고려하지 않아도 된다.

여기서 DP의 장점을 확인할 수 있다.

DP 삼각형을 활용하면 세 번째 줄의 값을 구할 때

두 번째 줄의 값만 확인하고, 첫 번째 줄의 값은 확인하지 않아도 된다.

왜냐하면 두 번째 줄에는 두 번째 줄까지의 모든 조합들 중 최고의 값만 남겨놨기 때문이다.

(이전의 정보를 확인할 필요가 없게 됨)

다섯 번째 줄까지의 최댓값은 30이며 이 값은 7-3-8-7-5 조합의 결과이다.

DP의 목적 : 메모리를 사용해서 중복 연산을 줄이고, 중복 연산을 줄여서 수행 속도를 개선한다.

메모리를 사용한다 : 배열 혹은 자료구조를 만든다.

중복 연산을 줄인다 : 연산한 결과를 배열에 담는다.

 

사실 'Dynamic Programming'보다 '기억하며 풀기 알고리즘'이 더 적합한 명칭인 거 같다.

 

DP 문제인지 확인하는 방법

1. DFS / BFS로 풀 수 있지만 경우의 수가 너무 많은 문제

(최대 경우의 수가 500만 개가 넘어간다면 DP로 풀이하는 게 효율적)

2. 경우의 수들에 중복적인 연산이 많은 경우

 

DP 유형의 경우 오래 붙잡고 있기 보다 30분 정도 고민(어떻게 하면 뒤로 돌아가지 않을 수 있을까) 후

답이 안 나오면 풀이를 참고해서 구현만 해보는 방식이 좋다.

현재 단계까지 연산을 잘 했다면 이 연산을 또 하지 않기 위해 어떤 정보를 어떻게 남겨야 할지 생각해 보자

'알고리즘 > DP' 카테고리의 다른 글

[알고리즘] DP-1  (0) 2022.08.31

+ Recent posts