diff --git a/alien-dictionary/imsosleepy.java b/alien-dictionary/imsosleepy.java
new file mode 100644
index 000000000..f71eca385
--- /dev/null
+++ b/alien-dictionary/imsosleepy.java
@@ -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();
+    }
+}
diff --git a/longest-palindromic-substring/imsosleepy.java b/longest-palindromic-substring/imsosleepy.java
new file mode 100644
index 000000000..faf919fdf
--- /dev/null
+++ b/longest-palindromic-substring/imsosleepy.java
@@ -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);
+    }
+}
diff --git a/rotate-image/imsosleepy.java b/rotate-image/imsosleepy.java
new file mode 100644
index 000000000..ec7f502af
--- /dev/null
+++ b/rotate-image/imsosleepy.java
@@ -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;
+            }
+        }
+    }
+}
diff --git a/subtree-of-another-tree/imsosleepy.java b/subtree-of-another-tree/imsosleepy.java
new file mode 100644
index 000000000..8c9f9d749
--- /dev/null
+++ b/subtree-of-another-tree/imsosleepy.java
@@ -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);
+    }
+}
diff --git a/validate-binary-search-tree/imsosleepy.java b/validate-binary-search-tree/imsosleepy.java
new file mode 100644
index 000000000..5290f91f0
--- /dev/null
+++ b/validate-binary-search-tree/imsosleepy.java
@@ -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);
+    }
+}