Skip to content

[Ackku] week 15 #1121

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 23, 2025
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
65 changes: 65 additions & 0 deletions alien-dictionary/imsosleepy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// 처음 봤을 때는 단순 노가다라 생각했는데, prefix 문제가 너무 까다로웠음
// 사이클 탐지도 마지막에 두면 더 편했는데 코드가 너무 길어지는거 같아서 GPT의 도움을 받았다.
// 다 정리하고 ㅂ니 코드 자체는 어렵지 않았음.
// 코치 여러분, 그리고 스터디 참여한 모두 수고하셨습니다.
public class AlienDictionary {
public String alienOrder(String[] words) {
Map<Character, Set<Character>> graph = new HashMap<>();
Map<Character, Integer> inDegree = new HashMap<>();

for (String word : words) {
for (char c : word.toCharArray()) {
graph.putIfAbsent(c, new HashSet<>());
inDegree.putIfAbsent(c, 0);
}
}

for (int i = 0; i < words.length - 1; i++) {
String first = words[i];
String second = words[i + 1];

// invalid case: prefix 문제
if (first.length() > second.length() && first.startsWith(second)) {
return "";
}

for (int j = 0; j < Math.min(first.length(), second.length()); j++) {
char c1 = first.charAt(j);
char c2 = second.charAt(j);
if (c1 != c2) {
if (!graph.get(c1).contains(c2)) {
graph.get(c1).add(c2);
inDegree.put(c2, inDegree.get(c2) + 1);
}
break;
}
}
}

PriorityQueue<Character> pq = new PriorityQueue<>();
for (char c : inDegree.keySet()) {
if (inDegree.get(c) == 0) {
pq.offer(c);
}
}

StringBuilder result = new StringBuilder();
while (!pq.isEmpty()) {
char current = pq.poll();
result.append(current);
for (char neighbor : graph.get(current)) {
inDegree.put(neighbor, inDegree.get(neighbor) - 1);
if (inDegree.get(neighbor) == 0) {
pq.offer(neighbor);
}
}
}

// invalid case: 사이클 문제
if (result.length() != inDegree.size()) {
return "";
}

return result.toString();
}
}
71 changes: 71 additions & 0 deletions longest-palindromic-substring/imsosleepy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// 투포인터와 유사한 방식의 풀이가 하나 더 있었음
// 다만 모든 문자열이 가운데가 될 수 있다는 조건이 너무 까다로워서 구현에는 실패함
// DP와 같은 O(N^2)이 되지만 공간사용량이 압도적으로 적어서 시간차이가 많이 나게 됨
// GPT의 도움을 받았음
class Solution {
public String longestPalindrome(String s) {
if (s == null || s.length() < 1) return "";

int start = 0, end = 0;

for (int i = 0; i < s.length(); i++) {
int len1 = expandAroundCenter(s, i, i);
int len2 = expandAroundCenter(s, i, i + 1);
int len = Math.max(len1, len2);


if (len > end - start) {
start = i - (len - 1) / 2;
end = i + len / 2;
}
}

return s.substring(start, end + 1);
}

private int expandAroundCenter(String s, int left, int right) {
while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
left--;
right++;
}
return right - left - 1;
}
}

// 가장 먼저 생각한 풀이. 회문하면 떠오르는게 DP인데 이런 방식을 바라는게 아닌거같음
class Solution {
public String longestPalindrome(String s) {
int n = s.length();
boolean[][] dp = new boolean[n][n];

int start = 0, maxLen = 1;

// 길이가 1인 경우
for (int i = 0; i < n; i++) {
dp[i][i] = true;
}

// 길이가 2인 경우
for (int i = 0; i < n - 1; i++) {
if (s.charAt(i) == s.charAt(i + 1)) {
dp[i][i + 1] = true;
start = i;
maxLen = 2;
}
}

for (int len = 3; len <= n; len++) {
for (int i = 0; i <= n - len; i++) {
int j = i + len - 1;

if (s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1]) {
dp[i][j] = true;
start = i;
maxLen = len;
}
}
}

return s.substring(start, start + maxLen);
}
}
24 changes: 24 additions & 0 deletions rotate-image/imsosleepy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// You have to rotate the image in-place 라는말을 별 생각 안하고 풀다가 오래걸림
// "matrix내"에서 문제의 요구사항 대로 회전시켜줘야 한다. 유지해야한다
// matrix[i][j]를 matrix[j][i]로 바꾸고 각 행을 좌우로 뒤집는다.
class Solution {
public void rotate(int[][] matrix) {
int n = matrix.length;

for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}

for (int i = 0; i < n; i++) {
for (int j = 0; j < n / 2; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[i][n - 1 - j];
matrix[i][n - 1 - j] = temp;
}
}
}
}
20 changes: 20 additions & 0 deletions subtree-of-another-tree/imsosleepy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// 이지문제가 아닌거 같다. 루트 노드를 반복 검증해야하는데 방법을 못 찾아서 오래걸림
// 시간 복잡도는 O(root의 길이*subRoot의 길이)
class Solution {
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
if (root == null) return false;

if (isSameTree(root, subRoot)) return true;

return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);
}

private boolean isSameTree(TreeNode a, TreeNode b) {
if (a == null && b == null) return true; // 둘 다 null이면 같음
if (a == null || b == null) return false; // 하나만 null이면 다름
if (a.val != b.val) return false; // 값이 다르면 다름

// DFS로 지속 검증
return isSameTree(a.left, b.left) && isSameTree(a.right, b.right);
}
}
17 changes: 17 additions & 0 deletions validate-binary-search-tree/imsosleepy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// 이진 탐색트리는 보통 O(N) ~ O(NlogN)을 요구한다.
// 그래서 이번에도 모든 노드를 한번만 탐색하는게 목표
// Node.val의 숫자 크기 때문에 Max_VALUE를 잘 지정해주면 바로 풀림
class Solution {
public boolean isValidBST(TreeNode root) {
return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE);
}

private boolean isValidBST(TreeNode node, long min, long max) {
if (node == null) return true;

if (node.val <= min || node.val >= max) return false;

return isValidBST(node.left, min, node.val) &&
isValidBST(node.right, node.val, max);
}
}