diff --git a/src/main/java/com/example/algorithm/data_structure/list/MyArrayList.java b/src/main/java/com/example/algorithm/data_structure/list/MyArrayList.java new file mode 100644 index 0000000..db32f13 --- /dev/null +++ b/src/main/java/com/example/algorithm/data_structure/list/MyArrayList.java @@ -0,0 +1,103 @@ +package com.example.algorithm.data_structure.list; + +import java.util.Arrays; + +public class MyArrayList implements MyList { + + // 타입 안정성 때문에 Object 타입 대신 제네릭 타입 사용 + private static final int DEFAULT_CAPACITY = 10; + private T[] elements; + private int size; + + + public MyArrayList() { + this.elements = (T[]) new Object[DEFAULT_CAPACITY]; + this.size = 0; + } + + @Override + public void add(T t) { + if(this.size == this.elements.length) { + this.elements = Arrays.copyOf(this.elements, this.size * 2); + } + + this.elements[this.size++] = t; + } + + @Override + public void insert(int index, T t) { + if(this.size == this.elements.length) { + this.elements = Arrays.copyOf(this.elements, this.size * 2); + } + + for (int i = this.size - 1; i >= index; i--) { + this.elements[i + 1] = this.elements[i]; + } + + this.elements[index] = t; + this.size++; + } + + @Override + public void clear() { + + } + + @Override + public boolean delete(T t) { + return false; + } + + @Override + public boolean deleteByIndex(int index) { + return false; + } + + @Override + public T get(int index) { + return null; + } + + @Override + public int indexOf(T t) { + return 0; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public boolean contains(T t) { + return false; + } + + @Override + public int size() { + return 0; + } + + public static void main(String[] args) { + MyArrayList list = new MyArrayList<>(); + list.add(1); + list.add(2); + list.add(3); + list.add(5); + list.add(6); + list.add(7); + list.add(8); + list.add(9); + list.add(10); + list.add(11); + + System.out.println(list.size); + System.out.println(Arrays.toString(list.elements)); + + list.insert(1, 4); + + System.out.println(list.size); + System.out.println(Arrays.toString(list.elements)); + } + +} diff --git a/src/main/java/com/example/algorithm/data_structure/list/MyList.java b/src/main/java/com/example/algorithm/data_structure/list/MyList.java new file mode 100644 index 0000000..5787f60 --- /dev/null +++ b/src/main/java/com/example/algorithm/data_structure/list/MyList.java @@ -0,0 +1,25 @@ +package com.example.algorithm.data_structure.list; + +public interface MyList { + + void add(T t); + + void insert(int index, T t); + + void clear(); + + boolean delete(T t); + + boolean deleteByIndex(int index); + + T get(int index); + + int indexOf(T t); + + boolean isEmpty(); + + boolean contains(T t); + + int size(); + +} diff --git a/src/main/java/com/example/algorithm/practice/BreadthFirstSearch.java b/src/main/java/com/example/algorithm/practice/BreadthFirstSearch.java new file mode 100644 index 0000000..e186902 --- /dev/null +++ b/src/main/java/com/example/algorithm/practice/BreadthFirstSearch.java @@ -0,0 +1,55 @@ +package com.example.algorithm.practice; + +public class BreadthFirstSearch { + + /* + * 너비 우선 탐색 풀이 방식 (Breadth First Search) + * 1. 시작 정점을 큐에 넣는다. + * 2. 큐에서 정점을 꺼내 방문한다. + * 3. 방문한 정점에서 인접한 정점 중 방문하지 않은 정점을 큐에 넣는다. + * 4. 큐가 빌 때까지 2~3을 반복한다. + * + * 너비 우선 탐색이 필요한 경우 대표 3 가지 + * 1. 최단 경로를 찾는 경우 + * 2. 임의의 경로를 찾는 경우 + * 3. 모든 정점을 방문하는 경우 + */ + + public void bfs(int[][] graph, boolean[] visited, int start) { + int[] queue = new int[graph.length]; + int front = 0; + int rear = 0; + + queue[rear++] = start; + visited[start] = true; + + while (front < rear) { + int current = queue[front++]; + System.out.print(current + " "); + + for (int i = 0; i < graph[current].length; i++) { + if (graph[current][i] == 1 && !visited[i]) { + queue[rear++] = i; + visited[i] = true; + } + } + } + } + + public static void main(String[] args) { + int[][] graph = { + {0, 1, 1, 0, 0, 0}, + {1, 0, 0, 1, 1, 0}, + {1, 0, 0, 0, 1, 0}, + {0, 1, 0, 0, 1, 1}, + {0, 1, 1, 1, 0, 1}, + {0, 0, 0, 1, 1, 0} + }; + + boolean[] visited = new boolean[graph.length]; + + BreadthFirstSearch bfs = new BreadthFirstSearch(); + bfs.bfs(graph, visited, 0); + } + +} diff --git a/src/main/java/com/example/algorithm/practice/DepthFirstSearch.java b/src/main/java/com/example/algorithm/practice/DepthFirstSearch.java new file mode 100644 index 0000000..59bb8a0 --- /dev/null +++ b/src/main/java/com/example/algorithm/practice/DepthFirstSearch.java @@ -0,0 +1,45 @@ +package com.example.algorithm.practice; + +public class DepthFirstSearch { + + /* + * 깊이 우선 탐색 풀이 방식 (Depth First Search) + * 1. 시작 정점을 스택에 넣는다. + * 2. 스택에서 정점을 꺼내 방문한다. + * 3. 방문한 정점에서 인접한 정점 중 방문하지 않은 정점을 스택에 넣는다. + * 4. 스택이 빌 때까지 2~3을 반복한다. + * + * 깊이 우선 탐색이 필요한 경우 대표 3 가지 + * 1. 그래프의 모든 정점을 방문하는 경우 + * 2. 그래프의 연결 요소를 찾는 경우 + * 3. 그래프의 사이클을 찾는 경우 + */ + + public void dfs(int[][] graph, boolean[] visited, int start) { + visited[start] = true; + System.out.print(start + " "); + + for (int i = 0; i < graph[start].length; i++) { + if (graph[start][i] == 1 && !visited[i]) { + dfs(graph, visited, i); + } + } + } + + public static void main(String[] args) { + int[][] graph = { + {0, 1, 1, 0, 0, 0}, + {1, 0, 0, 1, 1, 0}, + {1, 0, 0, 0, 1, 0}, + {0, 1, 0, 0, 1, 1}, + {0, 1, 1, 1, 0, 1}, + {0, 0, 0, 1, 1, 0} + }; + + boolean[] visited = new boolean[graph.length]; + + DepthFirstSearch dfs = new DepthFirstSearch(); + dfs.dfs(graph, visited, 0); + } + +} diff --git "a/src/main/java/com/example/algorithm/programmers/kakaoBlindRecruitment/k\354\247\204\354\210\230\354\227\220\354\204\234_\354\206\214\354\210\230_\352\260\234\354\210\230_\352\265\254\355\225\230\352\270\260.java" "b/src/main/java/com/example/algorithm/programmers/kakao/k\354\247\204\354\210\230\354\227\220\354\204\234_\354\206\214\354\210\230_\352\260\234\354\210\230_\352\265\254\355\225\230\352\270\260.java" similarity index 96% rename from "src/main/java/com/example/algorithm/programmers/kakaoBlindRecruitment/k\354\247\204\354\210\230\354\227\220\354\204\234_\354\206\214\354\210\230_\352\260\234\354\210\230_\352\265\254\355\225\230\352\270\260.java" rename to "src/main/java/com/example/algorithm/programmers/kakao/k\354\247\204\354\210\230\354\227\220\354\204\234_\354\206\214\354\210\230_\352\260\234\354\210\230_\352\265\254\355\225\230\352\270\260.java" index 4a6d0a4..b8a94f6 100644 --- "a/src/main/java/com/example/algorithm/programmers/kakaoBlindRecruitment/k\354\247\204\354\210\230\354\227\220\354\204\234_\354\206\214\354\210\230_\352\260\234\354\210\230_\352\265\254\355\225\230\352\270\260.java" +++ "b/src/main/java/com/example/algorithm/programmers/kakao/k\354\247\204\354\210\230\354\227\220\354\204\234_\354\206\214\354\210\230_\352\260\234\354\210\230_\352\265\254\355\225\230\352\270\260.java" @@ -1,4 +1,4 @@ -package com.example.algorithm.programmers.kakaoBlindRecruitment; +package com.example.algorithm.programmers.kakao; // 문제의 핵심: 소수판별에서의 효율적인 알고리즘 구현(시간복잡도) diff --git a/src/main/java/com/example/algorithm/programmers/lv1/Solution42748.java b/src/main/java/com/example/algorithm/programmers/lv1/Solution42748.java new file mode 100644 index 0000000..862b887 --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv1/Solution42748.java @@ -0,0 +1,51 @@ +package com.example.algorithm.programmers.lv1; + +import java.util.*; + +public class Solution42748 { + + // array : [1, 5, 2, 6, 3, 7, 4] + // commands : [[2, 5, 3], [4, 4, 1], [1, 7, 3]] + // return : [5, 6, 3] + + public int[] solution(int[] array, int[][] commands) { + int[] answer = new int[commands.length]; + + for (int i = 0; i < commands.length; i++) { + int startIndex = commands[i][0] - 1; + int endIndex = commands[i][1] - 1; + int targetIndex = commands[i][2] - 1; + + // 최소힙을 이용한 정렬 (부모노드는 항상 자식노드보다 작다) + PriorityQueue pq = new PriorityQueue<>((o1, o2) -> o1 - o2); + + for (int j = startIndex; j <= endIndex; j++) { + pq.offer(array[j]); + } + + for (int k = 0; k <= targetIndex; k++) { + // 값을 poll 할 때마다 최소값이 나오고 내부에서 정렬이 일어난다. + Integer targetVal = pq.poll(); + if (k == targetIndex) { + answer[i] = targetVal; + } + } + + pq.clear(); + } + + return answer; + } + + public static void main(String[] args) { + int[] array = {1, 5, 2, 6, 3, 7, 4}; + int[][] commands = {{2, 5, 3}, {4, 4, 1}, {1, 7, 3}}; + + Solution42748 solution = new Solution42748(); + + int[] answer = solution.solution(array, commands); + + System.out.println(Arrays.toString(answer)); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv1/Solution42840.java b/src/main/java/com/example/algorithm/programmers/lv1/Solution42840.java new file mode 100644 index 0000000..ed59536 --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv1/Solution42840.java @@ -0,0 +1,89 @@ +package com.example.algorithm.programmers.lv1; + +import java.util.*; + +public class Solution42840 { + + // answers : [1, 2, 3, 4, 5] + // return : [1] + + public int[] solution(int[] answers) { + List answer = new ArrayList<>(); + + int[] student1RandomSeq = {1, 2, 3, 4, 5}; + int[] student2RandomSeq = {2, 1, 2, 3, 2, 4, 2, 5}; + int[] student3RandomSeq = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5}; + + // 학생별 정답 수 + int[] studentsAnswerCount = new int[3]; + + // 정답 배열 인덱스 + int answersIndex = 0; + + // 학생별 찍는 번호 배열 인덱스 + int student1Index = 0; + int student2Index = 0; + int student3Index = 0; + + // 정답 수 계산 + while (answersIndex != answers.length) { + + // 학생별 정답 수 계산 + if (student1RandomSeq[student1Index] == answers[answersIndex]) { + studentsAnswerCount[0]++; + } + + if (student2RandomSeq[student2Index] == answers[answersIndex]) { + studentsAnswerCount[1]++; + } + + if (student3RandomSeq[student3Index] == answers[answersIndex]) { + studentsAnswerCount[2]++; + } + + // 배열 인덱스 증가 + if (student1Index == student1RandomSeq.length - 1) { + student1Index = 0; + }else { + student1Index++; + } + + if (student2Index == student2RandomSeq.length - 1) { + student2Index = 0; + }else { + student2Index++; + } + + if (student3Index == student3RandomSeq.length - 1) { + student3Index = 0; + }else { + student3Index++; + } + + answersIndex++; + } + + // 최대 정답 수 찾기 + for (int i = 0; i < studentsAnswerCount.length; i++) { + int maxVal = Arrays.stream(studentsAnswerCount).max().getAsInt(); + + if (studentsAnswerCount[i] == maxVal) { + answer.add(i + 1); + } + } + + // List -> int[] + return answer.stream().mapToInt(Integer::intValue).toArray(); + } + + public static void main(String[] args) { + int[] answers = {1, 2, 3, 4, 5}; + + Solution42840 solution = new Solution42840(); + + int[] answer = solution.solution(answers); + + System.out.println(Arrays.toString(answer)); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv1/Solution42862.java b/src/main/java/com/example/algorithm/programmers/lv1/Solution42862.java new file mode 100644 index 0000000..3b90f6e --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv1/Solution42862.java @@ -0,0 +1,66 @@ +package com.example.algorithm.programmers.lv1; + +import java.util.*; + +public class Solution42862 { + + // n : 5 + // lost : [2, 4] + // reserve : [1, 3, 5] + // return : 5 + + public int solution(int n, int[] lost, int[] reserve) { + int answer = n - lost.length; + + // 오름차순 정렬 + Arrays.sort(lost); + Arrays.sort(reserve); + + // 여벌 체육복을 가지고 있지만 도난 당한 경우 + for (int i = 0; i < lost.length; i++) { + for (int j = 0; j < reserve.length; j++) { + if (lost[i] == reserve[j]) { + lost[i] = -1; + reserve[j] = -1; + answer++; + break; + } + } + } + + // 여벌 체육복을 빌려줄 수 있는 경우 + for (int i = 0; i < lost.length; i++) { + if (lost[i] == -1) { + continue; + } + + for (int j = 0; j < reserve.length; j++) { + if (reserve[j] == -1) { + continue; + } + + if (lost[i] == reserve[j] - 1 || lost[i] == reserve[j] + 1) { + answer++; + lost[i] = -1; + reserve[j] = -1; + break; + } + } + } + + return answer; + } + + public static void main(String[] args) { + int n = 5; + int[] lost = {2, 3, 4}; + int[] reserve = {3, 4, 5}; + + Solution42862 solution = new Solution42862(); + + int answer = solution.solution(n, lost, reserve); + + System.out.println(answer); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv1/Solution86491.java b/src/main/java/com/example/algorithm/programmers/lv1/Solution86491.java new file mode 100644 index 0000000..865af3d --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv1/Solution86491.java @@ -0,0 +1,41 @@ +package com.example.algorithm.programmers.lv1; + +import java.util.Arrays; + +public class Solution86491 { + + // sizes : [[60, 50], [30, 70], [60, 30], [80, 40]] + // return : 4000 + + public int solution(int[][] sizes) { + int answer = 0; + + int maxW = 0; + int maxH = 0; + + // 가로, 세로 중 큰 값을 찾아서 저장 + for (int[] size : sizes) { + // 오름차순 정렬 + Arrays.sort(size); + + // 최대 가로, 세로 길이 저장 + maxW = Math.max(maxW, size[0]); + maxH = Math.max(maxH, size[1]); + } + + answer = maxW * maxH; + + return answer; + } + + public static void main(String[] args) { + int[][] sizes = {{60, 50}, {30, 70}, {60, 30}, {80, 40}}; + + Solution86491 solution = new Solution86491(); + + int answer = solution.solution(sizes); + + System.out.println(answer); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv2/Solution12909.java b/src/main/java/com/example/algorithm/programmers/lv2/Solution12909.java new file mode 100644 index 0000000..b077cf2 --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv2/Solution12909.java @@ -0,0 +1,50 @@ +package com.example.algorithm.programmers.lv2; + +import java.util.*; + +public class Solution12909 { + + // s : "()()" + // return : true + + boolean solution(String s) { + boolean answer = true; + + Stack stack = new Stack<>(); + + char[] array = s.toCharArray(); + + // 배열의 처음과 끝에 올바르지 않은 괄호가 있으면 false + if (array[s.length() - 1] == '(' || array[0] == ')') { + return false; + } + + for (char ch : array) { + if (ch == '(') { + stack.push(ch); + } else if (ch == ')') { + if (stack.isEmpty()) { + // 여는 괄호가 없는데 닫는 괄호가 나오면 올바르지 않은 괄호면 false + return false; + } + // 짝이 맞는 경우 스택에서 여는 괄호를 제거 + stack.pop(); + } + } + + // 스택에 남아 있는 괄호가 있는 경우에도 올바르지 않은 괄호먄 false + if (!stack.isEmpty()) { + return false; + } + + return answer; + } + + public static void main(String[] args) { + Solution12909 solution = new Solution12909(); + String s = "(()()"; + boolean answer = solution.solution(s); + System.out.println(answer); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv2/Solution42583.java b/src/main/java/com/example/algorithm/programmers/lv2/Solution42583.java new file mode 100644 index 0000000..ca88616 --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv2/Solution42583.java @@ -0,0 +1,61 @@ +package com.example.algorithm.programmers.lv2; + +import java.util.*; + +public class Solution42583 { + + // bridge_length : 2 + // weight : 10 + // truck_weights : [7, 4, 5, 6] + // return : 8 + + public int solution(int bridge_length, int weight, int[] truck_weights) { + int answer = 0; + int passed_truck_count = 0; + int truck_idx = 0; + int total_truck_weight = 0; + Queue bridge = new LinkedList<>(); + + while (passed_truck_count != truck_weights.length) { + // 다리를 건너는 트럭의 개수가 다리의 길이와 같다면 다리 끝에 도착을 의미 + if (bridge.size() == bridge_length) { + // 다리 끝에 있는 요소 꺼냄 + Integer truck_weight = bridge.poll(); + // 꺼낸 요소가 트럭이라면 지난 트럭 갯수 증가, 다리에 있는 트럭 총 무게 감소 + if (truck_weight != 0) { + passed_truck_count++; + total_truck_weight = total_truck_weight - truck_weight; + } + } + + // 다리가 수용 가능한 무게라면 다리에 트럭 추가 후 트럭 총 무게 증가, 트럭 인덱스 증가, 시간 증가 + if (truck_idx < truck_weights.length && total_truck_weight + truck_weights[truck_idx] <= weight) { + bridge.add(truck_weights[truck_idx]); + total_truck_weight = total_truck_weight + truck_weights[truck_idx]; + truck_idx++; + // 시간 증가 후 다음 루프로 이동 + answer++; + continue; + } + + // 아니라면 0추가 + bridge.add(0); + + // 시간 증가 + answer++; + } + + return answer; + } + + public static void main(String[] args) { + int bridge_length = 2; + int weight = 10; + int[] truck_weights = {7,4,5,6}; + + Solution42583 solution = new Solution42583(); + + System.out.println(solution.solution(bridge_length, weight, truck_weights)); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv2/Solution42584.java b/src/main/java/com/example/algorithm/programmers/lv2/Solution42584.java new file mode 100644 index 0000000..c1ecfb0 --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv2/Solution42584.java @@ -0,0 +1,46 @@ +package com.example.algorithm.programmers.lv2; + +import java.util.*; + +public class Solution42584 { + + // prices : [1, 2, 3, 2, 3] + // return : [4, 3, 1, 1, 0] + + public int[] solution(int[] prices) { + int[] answer = {}; + + // prices 배열의 길이만큼 answer 배열 생성 + answer = new int[prices.length]; + + // prices 배열의 길이만큼 반복 + for (int i = 0; i < prices.length; i++) { + // 현재 가격과 비교할 가격 + int currentPrice = prices[i]; + int count = 0; + // 현재 가격과 비교할 가격의 차이가 0보다 크고 현재 가격의 인덱스가 prices 배열의 길이보다 작다면 반복 + for (int j = i + 1; j < prices.length; j++) { + // 현재 가격과 비교할 가격의 차이가 0보다 크다면 count 증가 + if (currentPrice <= prices[j]) { + count++; + } else { + // 현재 가격과 비교할 가격의 차이가 0보다 작다면 count 증가 후 반복문 종료 + count++; + break; + } + } + // 현재 가격의 인덱스에 count를 저장 + answer[i] = count; + } + + return answer; + } + + public static void main(String[] args) { + Solution42584 solution = new Solution42584(); + int[] prices = {1, 2, 3, 2, 3}; + int[] answer = solution.solution(prices); + System.out.println(Arrays.toString(answer)); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv2/Solution42586.java b/src/main/java/com/example/algorithm/programmers/lv2/Solution42586.java new file mode 100644 index 0000000..5136553 --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv2/Solution42586.java @@ -0,0 +1,54 @@ +package com.example.algorithm.programmers.lv2; + +import java.util.*; + +public class Solution42586 { + + // progresses : [93, 30, 55] + // speeds : [1, 30, 5] + // return : [2, 1] + + public int[] solution(int[] progresses, int[] speeds) { + List answer = new ArrayList<>(); + + // 남은 일의 갯수 + int left = progresses.length; + + // 완료 지점 + int idx = 0; + + while (left > 0) { + int count = 0; + + for (int i = 0; i < progresses.length; i++) { + progresses[i] = progresses[i] + speeds[i]; + } + + for (int i = idx; i < progresses.length; i++) { + // 배포한 작업 카운트 + if (progresses[i] >= 100) { + count++; + idx++; + }else break; + } + + if (count != 0) { + answer.add(count); + left = left - count; + } + } + + return answer.stream() + .mapToInt(Integer::intValue) + .toArray(); + } + + public static void main(String[] args) { + Solution42586 solution = new Solution42586(); + int[] progresses = {93, 30, 55}; + int[] speeds = {1, 30, 5}; + int[] answer = solution.solution(progresses, speeds); + System.out.println(Arrays.toString(answer)); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv2/Solution42587.java b/src/main/java/com/example/algorithm/programmers/lv2/Solution42587.java new file mode 100644 index 0000000..2af159b --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv2/Solution42587.java @@ -0,0 +1,66 @@ +package com.example.algorithm.programmers.lv2; + +import java.util.*; + +public class Solution42587 { + + // priorities : [2, 1, 3, 2] + // location : 2 + // return : 1 + + public int solution(int[] priorities, int location) { + int answer = 0; + + Queue queue = new LinkedList<>(); + + for (int i = 0; i < priorities.length; i++) { + queue.add(new Process(i, priorities[i])); + } + + while (!queue.isEmpty()) { + Process currentProcess = queue.poll(); + + // 현재 프로세스보다 우선순위가 높은 프로세스가 있는지 확인 + boolean higherPriorityExist = queue.stream().anyMatch(p -> p.priority > currentProcess.priority); + + if (higherPriorityExist) { + // 더 높은 우선순위의 프로세스가 있으면 다시 큐에 추가 + queue.add(currentProcess); + } else { + // 높은 우선순위의 프로세스가 없으면 실행하고 정답 증가 + answer++; + // 만약 실행한 프로세스가 찾고자 하는 프로세스라면 종료 + if (currentProcess.location == location) { + break; + } + } + } + + return answer; + } + + class Process { + int location; + int priority; + + public Process(int location, int priority) { + this.location = location; + this.priority = priority; + } + } + + public static void main(String[] args) { + int[] priorities1 = {2, 1, 3, 2}; + int location1 = 2; + + Solution42587 solution = new Solution42587(); + + System.out.println(solution.solution(priorities1, location1)); + + int[] priorities2 = {1, 1, 9, 1, 1, 1}; + int location2 = 0; + System.out.println(solution.solution(priorities2, location2)); + } + +} + diff --git a/src/main/java/com/example/algorithm/programmers/lv2/Solution42626.java b/src/main/java/com/example/algorithm/programmers/lv2/Solution42626.java new file mode 100644 index 0000000..a401bbc --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv2/Solution42626.java @@ -0,0 +1,48 @@ +package com.example.algorithm.programmers.lv2; + +import java.util.PriorityQueue; + +public class Solution42626 { + + // scoville : [1, 2, 3, 9, 10, 12] + // K : 7 + // return : 2 + + public int solution(int[] scoville, int K) { + // 자바의 최소 힙 (부모 노드가 자식 노드보다 작거나 같은 완전 이진 트리) + // poll()하면 가장 작은 값 반환 + PriorityQueue pq = new PriorityQueue<>(); + + + // 최소 힙을 유지하면서 모든 음식의 스코빌 지수를 큐에 삽입 + for (int s : scoville) + pq.offer(s); + + int count = 0; + // 최소값이 K 이상이 될 때까지 반복 + while (pq.peek() < K) { + // 음식이 한 개만 남았는데도 K 이상의 스코빌 지수를 만들 수 없는 경우 + if (pq.size() == 1) + return -1; + + // 가장 맵지 않은 음식과 두 번째로 맵지 않은 음식을 섞어 새로운 음식의 스코빌 지수 계산 + int mixedScoville = pq.poll() + (pq.poll() * 2); + // 다시 정렬 + pq.offer(mixedScoville); + + count++; + } + + return count; + } + + public static void main(String[] args) { + int[] scoville = {1, 2, 3, 9, 10, 12}; + int K = 7; + + Solution42626 solution = new Solution42626(); + + System.out.println(solution.solution(scoville, K)); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv2/Solution42746.java b/src/main/java/com/example/algorithm/programmers/lv2/Solution42746.java new file mode 100644 index 0000000..17b50a0 --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv2/Solution42746.java @@ -0,0 +1,46 @@ +package com.example.algorithm.programmers.lv2; + +import java.util.*; + +public class Solution42746 { + + // numbers : [6, 10, 2] + // return : "6210" + + public String solution(int[] numbers) { + // Integer 배열을 String 배열로 변환 + String[] nums = new String[numbers.length]; + for (int i = 0; i < numbers.length; i++) { + nums[i] = String.valueOf(numbers[i]); + } + + // 정렬 기준 설정 + Arrays.sort(nums, (a, b) -> (b + a).compareTo(a + b)); + + System.out.println(Arrays.toString(nums)); + + // 모든 수가 0인 경우 예외 처리 + if (nums[0].equals("0")) { + return "0"; + } + + // 정렬된 문자열을 이어붙여 결과 반환 + StringBuilder sb = new StringBuilder(); + for (String num : nums) { + sb.append(num); + } + + return sb.toString(); + } + + public static void main(String[] args) { + int[] numbers = {3, 30, 34, 5, 9, 3, 30, 34, 5, 9,34, 5, 934, 5, 9}; + + Solution42746 solution = new Solution42746(); + + String answer = solution.solution(numbers); + + System.out.println(answer); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv2/Solution42747.java b/src/main/java/com/example/algorithm/programmers/lv2/Solution42747.java new file mode 100644 index 0000000..fdccf07 --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv2/Solution42747.java @@ -0,0 +1,38 @@ +package com.example.algorithm.programmers.lv2; + +import java.util.*; + +public class Solution42747 { + + // citations : [3, 0, 6, 1, 5] + // return : 3 + + public int solution(int[] citations) { + int answer = 0; + + // 오름차순 정렬 + Arrays.sort(citations); + + for (int i = 0; i < citations.length; i++) { + // h를 citations.length - i로 설정한 이유는 h번 이상 인용된 논문이 h편 이상이어야 하기 때문 + int h = citations.length - i; + if (citations[i] >= h) { + answer = h; + break; + } + } + + return answer; + } + + public static void main(String[] args) { + int[] citations = {3, 0, 6, 1, 5}; + + Solution42747 solution = new Solution42747(); + + int answer = solution.solution(citations); + + System.out.println(answer); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv2/Solution42839.java b/src/main/java/com/example/algorithm/programmers/lv2/Solution42839.java new file mode 100644 index 0000000..431fb7f --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv2/Solution42839.java @@ -0,0 +1,66 @@ +package com.example.algorithm.programmers.lv2; + +import java.util.*; + +public class Solution42839 { + + // numbers : "17" + // return : 3 + + public int solution(String numbers) { + int answer = 0; + + Set set = new HashSet<>(); + + // 순열을 이용하여 모든 경우의 수를 구함 + permutation("", numbers, set); + + // 소수 판별 + for (int num : set) { + if (isPrime(num)) { + answer++; + } + } + + return answer; + } + + // 소수 판별 + private boolean isPrime(int num) { + if (num < 2) { + return false; + } + + for (int i = 2; i <= Math.sqrt(num); i++) { + if (num % i == 0) { + return false; + } + } + + return true; + } + + // 순열 + private void permutation(String prefix, String numbers, Set set) { + int n = numbers.length(); + + if (!prefix.equals("")) { + set.add(Integer.valueOf(prefix)); + } + + for (int i = 0; i < n; i++) { + permutation(prefix + numbers.charAt(i), numbers.substring(0, i) + numbers.substring(i + 1, n), set); + } + } + + public static void main(String[] args) { + String numbers = "011"; + + Solution42839 solution = new Solution42839(); + + int answer = solution.solution(numbers); + + System.out.println(answer); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv2/Solution42842.java b/src/main/java/com/example/algorithm/programmers/lv2/Solution42842.java new file mode 100644 index 0000000..650fed7 --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv2/Solution42842.java @@ -0,0 +1,64 @@ +package com.example.algorithm.programmers.lv2; + +public class Solution42842 { + + // brown : 10, yellow : 2 + // return : [4, 3] + + public int[] solution(int brown, int yellow) { + int[] answer = new int[2]; + + // 전체 사이즈 + int size = brown + yellow; + + int width = 0; + int length = 0; + + // 가로, 세로 길이 구하기 + for (int i = 1; i <= size; i++) { + // 약수인 경우 + if (size % i == 0) { + // size를 i로 나눈 값이 세로 길이 + int newLength = size / i; + // size를 i로 나눈 나머지가 가로 길이 + int newWidth = i % size; + + int yellowSize = (newWidth - 2) * (newLength - 2); + + // 노란색 카펫의 사이즈와 일치하지 않는 경우 + if (yellowSize != yellow) { + continue; + } + + length = size / i; + width = i % size; + } + + // 가로가 세로보다 크거나 같은 경우 + if (length != 0 && width != 0) { + if (length <= width) { + break; + } + } + } + + answer[0] = width; + answer[1] = length; + + return answer; + } + + public static void main(String[] args) { + int brown = 18; + int yellow = 6; + + Solution42842 solution = new Solution42842(); + + int[] answer = solution.solution(brown, yellow); + + for (int i : answer) { + System.out.println(i); + } + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv2/Solution42860.java b/src/main/java/com/example/algorithm/programmers/lv2/Solution42860.java new file mode 100644 index 0000000..e818deb --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv2/Solution42860.java @@ -0,0 +1,45 @@ +package com.example.algorithm.programmers.lv2; + +public class Solution42860 { + + // name : "JEROEN" + // return : 56 + + public int solution(String name) { + int answer = 0; + + int length = name.length(); + + // 최대로 가질 수 있는 최대 이동 횟수 + int minMove = length - 1; + + for (int i = 0; i < length; i++) { + // 알파벳 변경 횟수 + answer += Math.min(name.charAt(i) - 'A', 'Z' - name.charAt(i) + 1); + + // 다음 알파벳이 A인 경우 + int next = i + 1; + while (next < length && name.charAt(next) == 'A') { + next++; + } + + // i번째 문자를 변경하고 다음 문자가 A가 아닌 경우 + minMove = Math.min(minMove, i + length - next + Math.min(i, length - next)); + } + + answer += minMove; + + return answer; + } + + public static void main(String[] args) { + String name = "JEROEN"; + + Solution42860 solution = new Solution42860(); + + int answer = solution.solution(name); + + System.out.println(answer); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv2/Solution42883.java b/src/main/java/com/example/algorithm/programmers/lv2/Solution42883.java new file mode 100644 index 0000000..d7e4e9a --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv2/Solution42883.java @@ -0,0 +1,50 @@ +package com.example.algorithm.programmers.lv2; + +public class Solution42883 { + + // number : "1924" / "1231234" / "4177252841" + // k : 2 / 3 / 4 + // return : "94" / "3234" / "775841" + + public String solution(String number, int k) { + String answer = ""; + + String[] num_arr = number.split(""); + + int len = number.length() - k; + int start = 0; + int end = k; + + for (int i = 0; i < len; i++) { + int max = 0; + int idx = 0; + + for (int j = start; j <= end; j++) { + int num = Integer.parseInt(num_arr[j]); + + if (max < num) { + max = num; + idx = j; + } + } + + answer += max; + start = idx + 1; + end++; + } + + return answer; + } + + public static void main(String[] args) { + String number = "4177252841"; + int k = 4; + + Solution42883 solution = new Solution42883(); + + String answer = solution.solution(number, k); + + System.out.println(answer); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv2/Solution43165.java b/src/main/java/com/example/algorithm/programmers/lv2/Solution43165.java index f38709e..540f80c 100644 --- a/src/main/java/com/example/algorithm/programmers/lv2/Solution43165.java +++ b/src/main/java/com/example/algorithm/programmers/lv2/Solution43165.java @@ -4,38 +4,31 @@ public class Solution43165 { // numbers : [1, 1, 1, 1, 1] // target : 3 // result : 5 + + // 결과값 저장 private static int cnt = 0; + // numbers 배열의 모든 경우의 수를 탐색하여 target과 일치하는 경우의 수를 구함 public int solution(int[] numbers, int target) { - // DFS를 이용해 풀이 - dfs(0, target, numbers); - + dfs(numbers, target, 0, 0); return cnt; } - public void dfs(int index, int target, int[] numbers) { - // 주어진 배열의 마지막 자리일 경우 - if (index == numbers.length) { - // sum 초기화 - int sum = 0; - - for (int i = 0; i < numbers.length; i++) { - // sum에 주어진 배열의 수를 더한다 - sum += numbers[i]; - } - // 배열을 모두 더한 값이 target과 같은 경우 + // 깊이 우선 탐색 + private void dfs(int[] numbers, int target, int sum, int depth) { + // numbers 배열의 모든 원소를 탐색한 경우 + if (depth == numbers.length) { + // target과 일치하는 경우의 수를 증가 if (sum == target) { cnt++; } - } - // 마지막 자리가 아닐 경우 재귀함수를 통해 부호를 바꿔가며 탐색 - else { - numbers[index] *= 1; - dfs(index + 1, target, numbers); - numbers[index] *= -1; - dfs(index + 1, target, numbers); + // 종료 + return; } + + dfs(numbers, target, sum + numbers[depth], depth + 1); + dfs(numbers, target, sum - numbers[depth], depth + 1); } public static void main(String[] args) { diff --git a/src/main/java/com/example/algorithm/programmers/lv2/Solution84512.java b/src/main/java/com/example/algorithm/programmers/lv2/Solution84512.java new file mode 100644 index 0000000..f7457b5 --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv2/Solution84512.java @@ -0,0 +1,49 @@ +package com.example.algorithm.programmers.lv2; + +public class Solution84512 { + + // word : "AAAAE" / "AAAE" / "I" / "EIO + // return : 6 / 10 / 1563 / 1189 + public int solution(String word) { + int answer = 0; + + // 풀이 설명 + // 1. 모음 배열을 만든다. + // 2. 각 모음 별로 가중치를 부여한다. + // 3. 각 자리수 별로 가중치를 부여한다. + // 4. 각 자리수 별로 모음이 나오면 가중치를 더한다. + + // 모음 배열 + String[] vowels = {"A", "E", "I", "O", "U"}; + + // 가중치 배열 + int[] multipliers = {781, 156, 31, 6, 1}; + + // 각 자리수 별로 가중치를 더한다. + for (int i = 0; i < word.length(); i++) { + // 각 자리수 별로 모음이 나오면 가중치를 더한다. + for (int j = 0; j < vowels.length; j++) { + // 모음이 나오면 가중치를 더한다. + if (vowels[j].equals(String.valueOf(word.charAt(i)))) { + // 가중치를 더한다. + answer += 1 + j * multipliers[i]; + // 모음이 나오면 종료 + break; + } + } + } + + return answer; + } + + public static void main(String[] args) { + String word = "AAAAE"; + + Solution84512 solution = new Solution84512(); + + int answer = solution.solution(word); + + System.out.println(answer); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv2/Solution86971.java b/src/main/java/com/example/algorithm/programmers/lv2/Solution86971.java new file mode 100644 index 0000000..874749b --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv2/Solution86971.java @@ -0,0 +1,92 @@ +package com.example.algorithm.programmers.lv2; + +import java.util.*; + +public class Solution86971 { + + // n : 9 + // wires : [[1,3],[2,3],[3,4],[4,5],[4,6],[4,7],[7,8],[7,9]] + // return : 3 + + // 반례 + // n :9 + // wires: [[1,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,8],[8,9]] + // return : 1 + + public int solution(int n, int[][] wires) { + int answer = 999999999; + + // 0번 인덱스는 사용하지 않음 + List> graph = new ArrayList<>(); + for (int i = 0; i <= n; i++) { + graph.add(new ArrayList<>()); + } + + // 인접 리스트 생성 + for (int[] wire : wires) { + graph.get(wire[0]).add(wire[1]); + graph.get(wire[1]).add(wire[0]); + System.out.println(graph); + } + + // 각 간선을 제거하고 bfs로 탐색 + for (int[] wire : wires) { + int v1 = wire[0]; + int v2 = wire[1]; + + // 간선 제거 + graph.get(v1).remove(Integer.valueOf(v2)); + graph.get(v2).remove(Integer.valueOf(v1)); + + int aCount = bfs(graph, v1, n); + int bCount = bfs(graph, v2, n); + + int diff = Math.abs(aCount - bCount); + + answer = Math.min(answer, diff); + + // 제거한 간선 복구 + graph.get(v1).add(v2); + graph.get(v2).add(v1); + } + + return answer; + } + + private int bfs(List> graph, int start, int n) { + Queue queue = new LinkedList<>(); + boolean[] visited = new boolean[n + 1]; + + queue.offer(start); + visited[start] = true; + + int count = 1; + + while (!queue.isEmpty()) { + int current = queue.poll(); + + // 현재 노드와 연결된 노드 탐색 + for (int next : graph.get(current)) { + if (!visited[next]) { + queue.offer(next); + visited[next] = true; + count++; + } + } + } + + return count; + } + + public static void main(String[] args) { + int n = 9; + int[][] wires = {{1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 7}, {7, 8}, {8, 9}}; + + Solution86971 solution = new Solution86971(); + + int answer = solution.solution(n, wires); + + System.out.println(answer); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv2/Solution87946.java b/src/main/java/com/example/algorithm/programmers/lv2/Solution87946.java new file mode 100644 index 0000000..26e32e5 --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv2/Solution87946.java @@ -0,0 +1,86 @@ +package com.example.algorithm.programmers.lv2; + +public class Solution87946 { + + // k : 80 + // dungeons : [[80,20],[50,40],[30,10]] + // result : 3 + + int answer = -1; + + public int solution(int k, int[][] dungeons) { + int dungeonCount = dungeons.length; + int[] arr = new int[dungeonCount]; + + for (int i = 0; i < dungeonCount; i++) { + arr[i] = i; + } + + permutation(arr, 0, dungeonCount, k, dungeons); + + return answer; + } + + // 가능한 순번 인덱스 구하가 후 순서대로 던전 탐험 + private void permutation(int[] indexSeq, int depth, int dungeonCount, int k, int[][] dungeons) { + if (depth == dungeonCount) { + int count = explore(indexSeq, k, dungeons); + + // 던전 탐험 횟수 최대값 저장 + if (answer < count) { + answer = count; + } + return; + } + + // 던전 탐험 횟수가 이미 최대값이면 종료 + if (answer == dungeonCount) { + return; + } + + for (int i = depth; i < dungeonCount; i++) { + swap(indexSeq, i, depth); + permutation(indexSeq, depth + 1, dungeonCount, k, dungeons); + swap(indexSeq, i, depth); + } + } + + // 순번 인덱스 교환 + private void swap(int[] indexSeq, int i, int j) { + int temp = indexSeq[i]; + indexSeq[i] = indexSeq[j]; + indexSeq[j] = temp; + } + + // 던전 탐험 + private int explore(int[] indexSeq, int k, int[][] dungeons) { + int count = 0; + for (int idx : indexSeq) { + // 유저의 피로도가 던전의 최소 필요 피로도보다 크거나 같으면 던전 탐험 + if (dungeons[idx][0] <= k) { + // 유저의 피로도 감소 + k -= dungeons[idx][1]; + // 던전 탐험 횟수 증가 + count++; + } else { + // 피로도가 만족되지 않으면 루프 종료 던전 탐험 불가능하면 종료 + break; + } + } + + return count; + } + + + public static void main(String[] args) { + int k = 80; + int[][] dungeons = {{80, 20}, {50, 40}, {30, 10}}; + + Solution87946 solution = new Solution87946(); + + int answer = solution.solution(k, dungeons); + + System.out.println(answer); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv3/Solution42627.java b/src/main/java/com/example/algorithm/programmers/lv3/Solution42627.java new file mode 100644 index 0000000..9d31e94 --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv3/Solution42627.java @@ -0,0 +1,65 @@ +package com.example.algorithm.programmers.lv3; + +import java.util.*; + +public class Solution42627 { + + // jobs : [[0, 3], [1, 9], [2, 6]] + // return : 9 + + public int solution(int[][] jobs) { + // 각 작업의 요청 시점부터 처리완료 시점까지의 합을 작업의 갯수로 나눈 값 + int answer = 0; + + // 작업이 요청되는 시점 기준으로 오름차순 정렬 * 핵심 + Arrays.sort(jobs, (o1, o2) -> o1[0] - o2[0]); + + // 작업의 소요시간 기준으로 오름차순 정렬 * 핵심 + PriorityQueue pq = new PriorityQueue<>((o1, o2) -> o1[1] - o2[1]); + + // 작업 배열 인덱스 + int jobs_index = 0; + // 처리 완료된 작업 개수 + int finish_job = 0; + // 작업 처리 완료 시간 디스크는 한번에 하나의 작업만 수행 가능하기 때문에 작업 완료 시점은 작 작업의 소요 시간의 합계 + int end_time = 0; + + while(true) { + // 모든 작업을 처리했다면 종료 + if(finish_job == jobs.length) break; + + // 작업 처리 중 요청된 작업 add + while(jobs_index < jobs.length && jobs[jobs_index][0] <= end_time) { + pq.add(jobs[jobs_index++]); + } + + // 이전 작업 처리 중 요청된 작업이 있는 경우 + if(!pq.isEmpty()) { + int[] job = pq.poll(); + // 대기시간 + 작업 소요시간 + // 작업 요청부터 종료까지 걸린 시간 추가 + answer += end_time - job[0] + job[1]; + // 작업 처리 완료 시간 갱신 + end_time += job[1]; + // 처리 완료된 작업 개수 1 증가 + finish_job++; + } + // 이전 작업 처리 중 요청된 작업이 없는 경우 + else { + end_time = jobs[jobs_index][0]; // 다음 작업 요청 시점으로 갱신 + } + } + + return answer / jobs.length; + + } + + public static void main(String[] args) { + int[][] jobs = {{0, 3}, {2, 6}, {1, 9}}; + + Solution42627 solution = new Solution42627(); + + System.out.println(solution.solution(jobs)); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/lv3/Solution42628.java b/src/main/java/com/example/algorithm/programmers/lv3/Solution42628.java new file mode 100644 index 0000000..9624ef0 --- /dev/null +++ b/src/main/java/com/example/algorithm/programmers/lv3/Solution42628.java @@ -0,0 +1,63 @@ +package com.example.algorithm.programmers.lv3; + +import java.util.Arrays; +import java.util.Collections; +import java.util.PriorityQueue; + +public class Solution42628 { + + // operations : ["I 16", "I -5643", "D -1", "D 1", "D 1", "I 123", "D -1"] + // return : [0, 0] + + public int[] solution(String[] operations) { + int[] answer = new int[2]; + + // 최소 힙 최소 : 값이 우선순위인 큐 + PriorityQueue pq = new PriorityQueue<>(); + + // 최대 힙 : 최대 값이 우선순위인 큐 + PriorityQueue reversePq = new PriorityQueue<>(Collections.reverseOrder()); + + for (String op : operations) { + String[] split = op.split(" "); + if (split[0].equals("I")) { + pq.offer(Integer.parseInt(split[1])); + reversePq.offer(Integer.parseInt(split[1])); + } + + if (split[0].equals("D")) { + if (pq.isEmpty() || reversePq.isEmpty()) { + continue; + } + + if (split[1].equals("1")) { + int max = reversePq.poll(); + pq.remove(max); + } else { + int min = pq.poll(); + reversePq.remove(min); + } + } + } + + if (pq.isEmpty() || reversePq.isEmpty()) { + return answer; + } + + answer[0] = reversePq.poll(); + answer[1] = pq.poll(); + + return answer; + } + + public static void main(String[] args) { + String[] operations = {"I 16", "I -5643", "D -1", "D 1", "D 1", "I 123", "D -1"}; + + Solution42628 solution = new Solution42628(); + + int[] answer = solution.solution(operations); + + System.out.println(Arrays.toString(answer)); + } + +} diff --git a/src/main/java/com/example/algorithm/programmers/permutation/Permutation.java b/src/main/java/com/example/algorithm/programmers/permutation/Permutation.java index ac29ef5..3d2f7fa 100644 --- a/src/main/java/com/example/algorithm/programmers/permutation/Permutation.java +++ b/src/main/java/com/example/algorithm/programmers/permutation/Permutation.java @@ -5,15 +5,15 @@ * ex) [1, 2] , [2, 1] 는 서로 다름 * */ public class Permutation { - public static void permutation(int[] arr, int[] out, boolean[] visited, int depth, int r){ - if(depth == r){ // 뽑으려는 갯수 r과 depth가 같으면 출력 - for(int num : out) System.out.print(num + " "); + public static void permutation(int[] arr, int[] out, boolean[] visited, int depth, int r) { + if (depth == r) { // 뽑으려는 갯수 r과 depth가 같으면 출력 + for (int num : out) System.out.print(num + " "); System.out.println(); return; // 재귀함수 탈출? } - for(int i = 0; i < arr.length; i++){ - if(!visited[i]){ + for (int i = 0; i < arr.length; i++) { + if (!visited[i]) { visited[i] = true; out[depth] = arr[i]; permutation(arr, out, visited, depth + 1, r); @@ -22,10 +22,10 @@ public static void permutation(int[] arr, int[] out, boolean[] visited, int dept } } - public static void main(String[] args){ - int[] arr = {1, 2, 3, 4}; - // 2개 뽑기 - int r = 4; + public static void main(String[] args) { + int[] arr = {6, 0, 4}; + // 3개 뽑기 + int r = 3; permutation(arr, new int[r], new boolean[arr.length], 0, r); } }