Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/week2/멀리뛰기/nonani/Solution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
## ✏️ [프로그래머스] 멀리 뛰기
📶 문제 난이도
Lv. 2

🔗 문제 링크
https://school.programmers.co.kr/learn/courses/30/lessons/12914?language=java

⏱️ 풀이 시간
5분

✅ 풀이 근거
고민할 필요없이 점화식이 피보나치 수열이었다.
2칸 전에 뛴 경우 + 1칸 전 뛴 경우 더해주기만 하면 되는 문제
*/
class Solution {
public long solution(int n) {

int[] dp = new int[2001];
dp[1] = 1;
dp[2] = 2;
for(int i=3;i<=n;i++) {
dp[i] = (dp[i-1] + dp[i-2]) % 1234567;
}
return dp[n];
}
}
78 changes: 78 additions & 0 deletions src/week2/섬 연결하기/nonani/Solution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
## ✏️ [프로그래머스] 섬 연결하기
📶 문제 난이도
Lv. 3

🔗 문제 링크
https://school.programmers.co.kr/learn/courses/30/lessons/42861?language=java

⏱️ 풀이 시간
30분

✅ 풀이 근거
//MST 구하는 문제
// Prim으로 풀어보자
// Prim은 엣지수가 많은 상황에서 이득을 볼 수 있는 알고리즘
// 만약 엣지수가 적은 상황에서는 크루스칼보단 성능이 떨어지는 상황이 나올 가능성이 높지만 그런 세부 지시사항은 없으니 뭘 선택하든 상관은 없을듯
*/





import java.util.*;

class Solution {
public int solution(int n, int[][] costs) {
int answer = 0;
boolean[] visited = new boolean[n];
int cnt = 0; // 방문한 정점 개수를 카운트, N이면 다 방문한거니까 더 진행할 필요가 없음

//int[0] : 다음으로 방문할 노드 번호, int[1] : 그 노드까지의 이동하는 거리(간선 거리)
PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> {
return Integer.compare(o1[1], o2[1]);
});

ArrayList<int[]> graph[] = new ArrayList[n];

for (int i = 0; i < n; i++) {
graph[i] = new ArrayList<int[]>();
}

for (int[] cost : costs) {
int a = cost[0];
int b = cost[1];
int c = cost[2];
graph[a].add(new int[]{b, c});
graph[b].add(new int[]{a, c});
}

//임의의 정점하나를 고른다.
pq.add(new int[]{0, 0});

while (!pq.isEmpty() && cnt < n) {
// 현재 pq에 있는 후보 정점 중 거리가 가장 짧은 걸 고른다.
int[] node = pq.poll();
int cur = node[0];
int dist = node[1];

if (visited[cur])
continue;

visited[cur] = true;
cnt++;
answer += dist;

// 다음 정점 후보를 고른다.
for (int i = 0; i < graph[cur].size(); i++) {
int[] nextNode = graph[cur].get(i);
int next = nextNode[0];
int cost = nextNode[1];
if (visited[next])
continue;
pq.add(new int[]{next, cost});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

처음에 제가 느낀 생각은 graph로 초기화하는 것이 costs의 전체 길이라면 그냥,
costs[2]로 Arraysort() 한 다음에 그냥 간선의 개수가 n - 1 이 될 때까지 visited한게 더 좋지 않을까 ? 생각했었던 것 같습니다!

뭔가 임의의 시작점에서 정해진 목표로 가는데 이용하면 최적의 효율로 찾을 수 있겠다?라고 생각이 드는데 모든 점이 연결되어야 하는 문제 상황에서 graph로 초기화해야 하나? 라는 생각입니다 ㅋㅎㅋㅎㅋ

사실 제가 틀릴 수도 있어서 아래는 두 알고리즘을 비교한, AI 답변 첨부 드립니다.

1. 입력 형태와 맞아요. costs가 이미 간선 리스트라서 정렬만 하면 끝. 프림은 인접 리스트를 따로 만들어야
  해서 코드가 더 길어져요.
2. "연결되어 있는지 확인"이 곧 union-find예요. find(a) == find(b) 한 줄이 그 질문에 대한 답이라, 문제의
  핵심 동작과 자료구조가 정확히 일치해요. 프림은 연결 여부를 visited로 간접 관리하죠.
3. 간선이 적은 그래프에 유리해요. 이 문제는 섬 100개 이하의 희소 그래프라 크루스칼 O(E log E)가
  자연스러워요. 프림(인접행렬 O(V²) 버전)이 이기는 건 간선이 V²에 가까운 밀집 그래프일 때예요.

아.. 풀이 그건에 이미 알고 있었군요 죄송합니다 ......

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

싸이클 체크하는게 귀찮아서 크루스칼은 조금 꺼려지더라구요 ㅋㅋㅋ
이 문제는 입력 데이터 형식부터 크루스칼 쓰라고 의도한 문제가 맞는 것 같습니다 🤣

}
}
return answer;
}
}
41 changes: 41 additions & 0 deletions src/week2/튜플/nonani/Solution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
## ✏️ [프로그래머스] 튜플
📶 문제 난이도
Lv. 2

🔗 문제 링크
https://school.programmers.co.kr/learn/courses/30/lessons/64065

⏱️ 풀이 시간
35분

✅ 풀이 근거
},{ 로 split하면 좋을 것 같다.
이후엔 길이를 기준으로 정렬한 뒤 visited set에 추가하다가 신규로 추가된 녀석을 배열에 추가는 식으로 하면 정렬도 깔끔하게 될 것 같았다.
*/

import java.util.*;

class Solution {
public int[] solution(String s) {

String[] subStrings = s.substring(2, s.length() - 2).split("\\},\\{");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 💯 !

String str = "";
Set<Integer> visited = new HashSet<>();
int[] answer = new int[subStrings.length];
int index = 0;

Arrays.sort(subStrings, (o1, o2) -> Integer.compare(o1.length(), o2.length()));
for (String sub : subStrings) {
for (String number : sub.split(",")) {
int value = Integer.parseInt(number);

if (visited.add(value)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set.add() 반환값이 boolean 이군요! 새로운거 알아갑니다 👍 👍

answer[index++] = value;
break;
}
}
}
return answer;
}
}