-
-
Notifications
You must be signed in to change notification settings - Fork 195
[ackku] Week 5 #882
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
[ackku] Week 5 #882
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// 투포인터를 쓸 필요 없음. 그냥 최소값을 찾아 빼주면 O(N)의 시간 복잡도를 얻을 수 있다. | ||
// 투포인터와 큰 차이가 없는 이유는 투포인터도 O(N)이기 때문. 아주 약간의 공간복잡도 차이만 있을 듯 | ||
// 결과는 큰 차이 없으나 알고리즘 자체가 더 쉽다. | ||
class Solution { | ||
public int maxProfit(int[] prices) { | ||
int minPrice = Integer.MAX_VALUE; | ||
int maxProfit = 0; | ||
|
||
for (int price : prices) { | ||
if (price < minPrice) { | ||
minPrice = price; | ||
} else { | ||
maxProfit = Math.max(maxProfit, price - minPrice); | ||
} | ||
} | ||
|
||
return maxProfit; | ||
} | ||
} | ||
|
||
// 처음 생각한 투포인터 방식 | ||
class Solution { | ||
public int maxProfit(int[] prices) { | ||
int left = 0; | ||
int right = 1; | ||
int maxProfit = 0; | ||
|
||
while (right < prices.length) { | ||
if (prices[left] < prices[right]) { | ||
int profit = prices[right] - prices[left]; | ||
maxProfit = Math.max(maxProfit, profit); | ||
} else { | ||
left = right; | ||
} | ||
right++; | ||
} | ||
|
||
return maxProfit; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// 아이디어로 푸는 문제라 선호하지 않는 문제... | ||
// 그냥 사용하지 않는 것을 구분자로 두고 스플릿하는게 가장 편하다. 아예 나오지 않을 문자를 기준으로 두면 길이를 알 필요가 없기 때문 | ||
public class Solution { | ||
// 인코딩 메서드 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이건 사소한 건데 Delimeter를 인스턴스 변수로 두고 쓰면 좋을 거 같아요 |
||
public String encode(List<String> strs) { | ||
StringBuilder encodedString = new StringBuilder(); | ||
|
||
for (String str : strs) { | ||
encodedString.append(str.length()).append("#").append(str); | ||
} | ||
|
||
return encodedString.toString(); | ||
} | ||
|
||
// 디코딩 메서드 | ||
public List<String> decode(String s) { | ||
List<String> decodedList = new ArrayList<>(); | ||
int i = 0; | ||
|
||
while (i < s.length()) { | ||
|
||
int j = i; | ||
while (s.charAt(j) != '#') { | ||
j++; | ||
} | ||
|
||
int length = Integer.parseInt(s.substring(i, j)); | ||
decodedList.add(s.substring(j + 1, j + 1 + length)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 자바 초보라 여쭤봐요.. |
||
|
||
i = j + 1 + length; | ||
} | ||
|
||
return decodedList; | ||
} | ||
} | ||
// 🚀를 기준으로 문자열을 분리 | ||
// @!#$@#$ 이런걸 스플릿 문자로 두는 방법도 있다.아이온 | ||
public class Solution { | ||
|
||
public String encode(List<String> strs) { | ||
StringBuilder encodedString = new StringBuilder(); | ||
|
||
for (String str : strs) { | ||
encodedString.append(str).append("🚀"); | ||
} | ||
|
||
return encodedString.toString(); | ||
} | ||
|
||
public List<String> decode(String s) { | ||
String[] parts = s.split("🚀"); | ||
List<String> decodedList = new ArrayList<>(); | ||
for (String part : parts) { | ||
if (!part.isEmpty()) { | ||
decodedList.add(part); | ||
} | ||
} | ||
|
||
return decodedList; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// 모든 단어를 정렬해야하기 때문에 시간 복잡도가 꽤 나오는 문제 | ||
// 하지만 모든 단어를 정렬해도 된다는건 글자 수가 100자 제한이 있어서 유추할 수 있다. | ||
// O(N) * O(MlogM) N 배열 길이, M 글자수의 시간복잡도가 나옴 | ||
class Solution { | ||
public List<List<String>> groupAnagrams(String[] strs) { | ||
HashMap<String,List<String>> anagrams = new HashMap<>(); | ||
for(String str: strs) { | ||
char[] charArray = str.toCharArray(); | ||
Arrays.sort(charArray); | ||
String sortedWord = new String(charArray); | ||
anagrams.computeIfAbsent(sortedWord, k -> new ArrayList<>()).add(str); | ||
} | ||
|
||
return new ArrayList<>(anagrams.values()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// GPT의 풀이. 트리를 이용해 O(m)으로 해결했다. | ||
public class Trie { | ||
private class TrieNode { | ||
TrieNode[] children; | ||
boolean isEndOfWord; | ||
|
||
public TrieNode() { | ||
children = new TrieNode[26]; // 알파벳 a~z (26개의 자식 노드) | ||
isEndOfWord = false; // 해당 노드가 단어의 끝인지 아닌지 나타냄 | ||
} | ||
} | ||
|
||
private TrieNode root; | ||
|
||
public Trie() { | ||
root = new TrieNode(); // 루트 노드 초기화 | ||
} | ||
|
||
public void insert(String word) { | ||
TrieNode node = root; | ||
for (char c : word.toCharArray()) { | ||
int index = c - 'a'; // 알파벳을 0-25의 숫자로 변환 | ||
if (node.children[index] == null) { | ||
node.children[index] = new TrieNode(); // 해당 문자가 없으면 새 노드를 생성 | ||
} | ||
node = node.children[index]; // 자식 노드로 이동 | ||
} | ||
node.isEndOfWord = true; // 단어의 끝을 표시 | ||
} | ||
|
||
public boolean search(String word) { | ||
TrieNode node = root; | ||
for (char c : word.toCharArray()) { | ||
int index = c - 'a'; | ||
if (node.children[index] == null) { | ||
return false; // 해당 문자가 없으면 false 반환 | ||
} | ||
node = node.children[index]; // 자식 노드로 이동 | ||
} | ||
return node.isEndOfWord; // 단어의 끝인지를 확인 | ||
} | ||
|
||
public boolean startsWith(String prefix) { | ||
TrieNode node = root; | ||
for (char c : prefix.toCharArray()) { | ||
int index = c - 'a'; | ||
if (node.children[index] == null) { | ||
return false; // 해당 접두사로 시작하는 단어가 없으면 false 반환 | ||
} | ||
node = node.children[index]; // 자식 노드로 이동 | ||
} | ||
return true; // 접두사로 시작하는 단어가 있으면 true 반환 | ||
} | ||
} | ||
|
||
// 백트래킹으로 풀어봤는데, 속도가 너무 안나왔음 | ||
// O(n*m)의 시간복잡도가 나옴. n은 글자수 m은 글자길이 | ||
class Trie { | ||
|
||
private List<String> words; | ||
|
||
public Trie() { | ||
words = new ArrayList<>(); | ||
} | ||
|
||
public void insert(String word) { | ||
words.add(word); | ||
} | ||
|
||
public boolean search(String word) { | ||
return backtrack(word, true); | ||
} | ||
|
||
public boolean startsWith(String prefix) { | ||
return backtrack(prefix, false); | ||
} | ||
|
||
private boolean backtrack(String target, boolean exactMatch) { | ||
for (String word : words) { | ||
if (exactMatch) { | ||
if (word.equals(target)) { | ||
return true; | ||
} | ||
} else { | ||
if (word.startsWith(target)) { | ||
return true; | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// dp 배열 (dp[i] = s[0...i]가 단어들로 나눠질 수 있는지 여부) | ||
// 입력 데이터의 크기가 크지 않아서 O(N^2)도 가능한 문제. | ||
class Solution { | ||
public boolean wordBreak(String s, List<String> wordDict) { | ||
Set<String> wordSet = new HashSet<>(wordDict); | ||
boolean[] dp = new boolean[s.length() + 1]; | ||
dp[0] = true; | ||
|
||
for (int i = 1; i <= s.length(); i++) { | ||
for (int j = 0; j < i; j++) { | ||
if (dp[j] && wordSet.contains(s.substring(j, i))) { | ||
dp[i] = true; | ||
break; | ||
} | ||
} | ||
} | ||
|
||
return dp[s.length()]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 좋은 풀이 잘 보고 갑니다. |
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2가지 방식을 모두 생각해보신 것 너무 좋은데요?
저는 풀기에 바빴는데, 배우고 갑니다