Skip to content

[Tessa1217] Week 05 Solution #1405

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 5 commits into from
May 2, 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
33 changes: 33 additions & 0 deletions best-time-to-buy-and-sell-stock/Tessa1217.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* 주식 가격이 주어지는 prices 배열이 있을 때 최대 주식 이익을 구하시오
* 주식을 산 날짜에는 팔 수 없으며 반드시 산 날짜의 이후 날짜부터(미래부터) 팔 수 있다.
*/
class Solution {
public int maxProfit(int[] prices) {
int maxProfit = 0;
int min = prices[0];
// 굳이 DP 배열 쓰지 않고 계산, 공간 복잡도 낮추기
for (int i = 0; i < prices.length; i++) {
int profit = prices[i] - min;
maxProfit = Math.max(profit, maxProfit);
min = Math.min(prices[i], min);
}
return maxProfit;
}

// public int maxProfit(int[] prices) {
// // 최저 구매
// int[] dp = new int[prices.length];
// dp[0] = prices[0];
// for (int i = 1; i < prices.length; i++) {
// dp[i] = Math.min(prices[i], dp[i - 1]);
// }
// // 최저 구매 배열 기준으로 당일 최대 이익 계산
// int profit = 0;
// for (int i = 1; i < prices.length; i++) {
// profit = Math.max(prices[i] - dp[i - 1], profit);
// }
// return profit;
// }
}

39 changes: 39 additions & 0 deletions encode-and-decode-strings/Tessa1217.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* 문자열에 대한 encode, decode 알고리즘 디자인
* 문자열은 ASCII 256 모두 포함 가능 (문자만 포함한 게 아니므로 특수문자(:, ?) 등도 알고리즘 내에서 고려해야 함
* */

import java.util.ArrayList;
import java.util.List;

public class Solution {

public static String encode(List<String> strs) {
StringBuilder sb = new StringBuilder();
for (String str : strs) {
// : 구분자 앞에 단어의 길이 추가
sb.append(str.length()).append(":").append(str);
}
return sb.toString();
}

public static List<String> decode(String str) {
List<String> words = new ArrayList<>();
int i = 0;
while (i < str.length()) {
// 구분자 기준 인덱스
int colonIdx = str.indexOf(':', i);
// 단어의 길이 인덱스
int length = Integer.parseInt(str.substring(i, colonIdx));
// 단어 시작
int wordStart = colonIdx + 1;
// 단어의 끝
int wordEnd = wordStart + length;
words.add(str.substring(wordStart, wordEnd));
i = wordEnd;
}
return words;
}

}

21 changes: 21 additions & 0 deletions group-anagrams/Tessa1217.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* 문자열 배열 strs가 주어질 때 애너그램인 문자들끼리 묶어서 반환하세요.
*/
class Solution {
// 시간복잡도: O(n * L log L)
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> anagramMap = new HashMap<>();
for (String str : strs) {
char[] word = str.toCharArray();
Arrays.sort(word);
String sortedCharacter = String.valueOf(word);
if (!anagramMap.containsKey(sortedCharacter)) {
anagramMap.put(sortedCharacter, new ArrayList<>());
}
anagramMap.get(sortedCharacter).add(str);
}
return new ArrayList(anagramMap.values());
}

}

86 changes: 86 additions & 0 deletions implement-trie-prefix-tree/Tessa1217.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* trie는 효율적으로 데이터를 저장하고 키를 통해 문자열 데이터 셋을 검색할 수 있는 트리 구조이다.
* 해당 구조를 활용해 자동완성이나 스펠링 체크를 만들 수 있다.
trie 클래스는 다음과 같이 구현할 수 있다.
Trie() 클래스 생성자
void insert(String word) : trie로 문자열 word를 삽입
boolean search(String word) : 문자열 word가 trie에 있다면 true를 반환
boolean startsWith(String prefix) : prefix가 trie에 있다면 true를 반환
*/
class Trie {

private Node root;

public Trie() {
root = new Node();
}

public void insert(String word) {
Node current = root;
for (char c : word.toCharArray()) {
if (!current.getNodeCharacters().containsKey(c)) {
current.getNodeCharacters().put(c, new Node());
}
current = current.getNodeCharacters().get(c);
}
current.setEnd();
}

public boolean search(String word) {
Node current = root;
for (char c : word.toCharArray()) {
if (!current.getNodeCharacters().containsKey(c)) {
return false;
}
current = current.getNodeCharacters().get(c);
}
return current.getEnd();
}

public boolean startsWith(String prefix) {
Node current = root;
for (char c : prefix.toCharArray()) {
if (!current.getNodeCharacters().containsKey(c)) {
return false;
}
current = current.getNodeCharacters().get(c);
}
return true;
}

static class Node {

// 문자열 끝 여부
private boolean isEnd;

// 키 추출을 위한 맵 구조
private Map<Character, Node> nodeCharacters;

Node() {
nodeCharacters = new HashMap<>();
isEnd = false;
}

public boolean getEnd() {
return this.isEnd;
}

public void setEnd() {
this.isEnd = true;
}

public Map<Character, Node> getNodeCharacters() {
return this.nodeCharacters;
}

}
}

/**
* Your Trie object will be instantiated and called as such:
* Trie obj = new Trie();
* obj.insert(word);
* boolean param_2 = obj.search(word);
* boolean param_3 = obj.startsWith(prefix);
*/

25 changes: 25 additions & 0 deletions word-break/Tessa1217.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* 문자열 s가 주어질 때 wordDict의 단어 문자열로 s가 구성될 수 있는지 여부를 반환하세요.
*/
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
int n = s.length();
boolean[] dp = new boolean[n + 1];
dp[0] = true;

// contains 최적화를 위해 Set 선언: 시간 복잡도: O(n^2)
Set<String> wordSet = new HashSet<>(wordDict);

for (int i = 1; i <= n; i++) {
for (int j = 0; j < i; j++) {
String word = s.substring(j, i);
if (dp[j] && wordSet.contains(word)) {
dp[i] = true;
break;
}
}
}
return dp[n];
}
}