diff --git a/alien-dictionary/Tessa1217.java b/alien-dictionary/Tessa1217.java new file mode 100644 index 000000000..68a45f6b8 --- /dev/null +++ b/alien-dictionary/Tessa1217.java @@ -0,0 +1,91 @@ +import java.util.*; + +public class Solution { + + /** + * @param words: a list of words + * @return: a string which is correct order + */ + // 라틴 알파벳을 쓰는 새로운 외계 문자가 있다. 하지만 문자의 순서는 알지 못한다. + // 새로운 언어의 규칙에 맞는 사전식 순서(알파벳 순서)로 정의된 non-empty(비지 않은 상태인) 단어 목록을 받았다. + // 이 언어의 순서를 찾으시오. + public String alienOrder(String[] words) { + + // wrt wrf => wr은 공통 t가 f보다 먼저 나왔으므로 t < f + // wrt er => w보다 e가 뒤에 나왔으므로 w < e + // er ett => r이 t보다 뒤에 나왔으므로 r < t + // ett rftt => r이 e보다 뒤에 나왔으므로 e < r + + Map> graph = new HashMap<>(); + Map char_order = new HashMap<>(); + + for (String word : words) { + for (char c : word.toCharArray()) { + graph.putIfAbsent(c, new HashSet<>()); + char_order.putIfAbsent(c, 0); + } + } + + for (int i = 0; i < words.length - 1; i++) { + String cur_word = words[i]; + String next_word = words[i + 1]; + + if (cur_word.length() > next_word.length() && cur_word.startsWith(next_word)) { + return ""; + } + + // 비교: (wrt, wrf) => t와 f 비교 + // 비교: (wrf, er) => w와 e 비교 + for (int j = 0; j < Math.min(cur_word.length(), next_word.length()); j++) { + char c1 = cur_word.charAt(j); + char c2 = next_word.charAt(j); + + // from "wrt"and"wrf" ,we can get 't'<'f' + // from "wrt"and"er" ,we can get 'w'<'e' + // from "er"and"ett" ,we can get 'r'<'t' + // from "ett"and"rftt" ,we can get 'e'<'r' + // 순서 저장 + if (c1 != c2) { + if (!graph.get(c1).contains(c2)) { + graph.get(c1).add(c2); + char_order.put(c2, char_order.get(c2) + 1); + } + break; + } + } + } + + Queue queue = new LinkedList<>(); + for (char c : char_order.keySet()) { + // 최상위 부터 queue에 삽입 => w + if (char_order.get(c) == 0) { + queue.offer(c); + } + } + + StringBuilder sb = new StringBuilder(); + while (!queue.isEmpty()) { + char cur = queue.poll(); + sb.append(cur); + + // 연관 글자들의 순서 조정 => w의 연관 글자들 => e, e와 연관 글자들 => t, t와 연관 글자들 => f ... + for (char linked_char : graph.get(cur)) { + char_order.put(linked_char, char_order.get(linked_char) - 1); + if (char_order.get(linked_char) == 0) { + queue.offer(linked_char); + } + } + } + + if (sb.length() != char_order.size()) { + return ""; + } + + return sb.toString(); + + } + +} + + + diff --git a/construct-binary-tree-from-preorder-and-inorder-traversal/Tessa1217.java b/construct-binary-tree-from-preorder-and-inorder-traversal/Tessa1217.java new file mode 100644 index 000000000..f67f820da --- /dev/null +++ b/construct-binary-tree-from-preorder-and-inorder-traversal/Tessa1217.java @@ -0,0 +1,65 @@ +import java.util.HashMap; +import java.util.Map; + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + + private Map inorderIndexMap; + private int preorderIndex = 0; + + public TreeNode buildTree(int[] preorder, int[] inorder) { + + inorderIndexMap = new HashMap<>(); + for (int i = 0; i < inorder.length; i++) { + inorderIndexMap.put(inorder[i], i); + } + + return buildTree(preorder, 0, inorder.length - 1); + + } + + private TreeNode buildTree(int[] preorder, int start, int end) { + if (start > end) { + return null; + } + + int rootVal = preorder[preorderIndex++]; + // root 생성 + TreeNode root = new TreeNode(rootVal); + + int inorderIndex = inorderIndexMap.get(rootVal); + + // 분할 정복 방식으로 좌측과 우측 트리에 대한 정보 탐색 + // preorder의 0번째 = head + // inorder 기준으로 봤을 때 + // root의 좌측은 좌측 서브트리, 우측은 우측 서브트리 + // 좌우측 서브트리를 각각 분할해서 탐색 진행 + // 분할한 preorder의 첫번째 노드 = 해당 트리의 head + // depth 0 => head 3, left side => [9], right side => [15, 20, 7] + // depth 1 => + // left => head 9 => search node 더 이상 없음 + // right => head 20 => left side => [15], right side => [7] + // depth 2 => + // left => head 15 => 더는 탐색할 노드 없음 + // right => head 7 => 더는 탐색할 노드 없음 + root.left = buildTree(preorder, start, inorderIndex - 1); + root.right = buildTree(preorder, inorderIndex + 1, end); + + return root; + } +} + diff --git a/longest-palindromic-substring/Tessa1217.java b/longest-palindromic-substring/Tessa1217.java new file mode 100644 index 000000000..b992a1f7e --- /dev/null +++ b/longest-palindromic-substring/Tessa1217.java @@ -0,0 +1,42 @@ +class Solution { + + // 시간복잡도: O(N^2) + public String longestPalindrome(String s) { + + // 회문 구성 불가 경우 + if (s == null || s.length() < 1) { + return ""; + } + + String result = ""; + + for (int i = 0; i < s.length(); i++) { + String odd = palindrome(s, i, i); + String even = palindrome(s, i, i + 1); + + if (odd.length() > result.length()) { + result = odd; + } + if (even.length() > result.length()) { + result = even; + } + + } + + return result; + + } + + private String palindrome(String s, int left, int right) { + + // 중앙을 기준으로 좌우 회문 여부 검사 + while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) { + left--; + right++; + } + + return s.substring(left + 1, right); + } + +} + diff --git a/rotate-image/Tessa1217.java b/rotate-image/Tessa1217.java new file mode 100644 index 000000000..3e201cd8d --- /dev/null +++ b/rotate-image/Tessa1217.java @@ -0,0 +1,70 @@ +class Solution { + + // 공간복잡도 개선 및 별도의 방문 배열 처리 등 하지 않기 위해 + // 2nd 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; + } + } + + // 열 자리 swap 하기 + // ex) 3 X 3 => 0 <-> 2 열 스왑 + // ex) 4 x 4 => 0 <-> 3, 1 <-> 2 스왑 + 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; + } + } + } + + + // public void rotate(int[][] matrix) { + + // [0, 0], [0, 1], [0, 2] [2, 0], [1, 0], [0, 0] + // [1, 0], [1, 1], [1, 2] [2, 1], [1, 1], [0, 1] + // [2, 0], [2, 1], [2, 2] [2, 2], [2, 1], [0, 2] + + + // [0, 0], [0, 1], [0, 2], [0, 3] [3, 0], [2, 0], [1, 0], [0, 0] + // [1, 0], [1, 1], [1, 2], [1, 3] [3, 1], [2, 1], [1, 1], [0, 1] + // [2, 0], [2, 1], [2, 2], [2, 3] [3, 2], [2, 2], [1, 2], [0, 2] + // [3, 0], [3, 1], [3, 2], [3, 3] [3, 3], [2, 3], [1, 3], [0, 3] + + // 90D => + // n = matrix.length이고 m = matrix[0].length일 때 + // 1 => 3 matrix[0][0] => matrix[0][2] + // 2 => 6 matrix[0][1] => matrix[1][2] + // 3 => 9 matrix[0][2] => matrix[2][2] + // matrix[i][j] => matrix[j][n - 1 - i] + + // int n = matrix.length; + // int m = matrix[0].length; + + // boolean[][] visited = new boolean[n][m]; + + // for (int i = 0; i < n; i++) { + // for (int j = 0; j < m; j++) { + // if (visited[i][j]) { + // continue; + // } + // int temp = matrix[i][j]; + // matrix[i][j] = matrix[j][n - 1 - i]; + // matrix[j][n - 1 - i] = temp; + + // visited[i][j] = true; + // visited[j][n - 1 - i] = true; + // } + // } + // } +} + diff --git a/subtree-of-another-tree/Tessa1217.java b/subtree-of-another-tree/Tessa1217.java new file mode 100644 index 000000000..54ff45a4f --- /dev/null +++ b/subtree-of-another-tree/Tessa1217.java @@ -0,0 +1,46 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode() {} + * TreeNode(int val) { this.val = val; } + * TreeNode(int val, TreeNode left, TreeNode right) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +class Solution { + public boolean isSubtree(TreeNode root, TreeNode subRoot) { + // subtree null일 경우 + if (subRoot == null) { + return true; + } + // 이진 트리가 null일 경우 + if (root == null) { + return false; + } + // subtree라면 + if (isIdentical(root, subRoot)) { + return true; + } + + return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot); + + } + + // isIdentical(s,t)= s.val==t.val AND isIdentical(s.left,t.left) AND isIdentical(s.right,t.right) + private boolean isIdentical(TreeNode r, TreeNode s) { + if (r == null || s == null) { + return r == null && s == null; + } + if (r.val != s.val) { + return false; + } + return isIdentical(r.left, s.left) && isIdentical(r.right, s.right); + } +} +