-
-
Notifications
You must be signed in to change notification settings - Fork 195
[GangBean] Week 5 #846
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
[GangBean] Week 5 #846
Changes from all commits
6bbd720
90a3376
218f757
b1f1306
b115010
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,30 @@ | ||
class Solution { | ||
public int maxProfit(int[] prices) { | ||
/** | ||
1. understanding | ||
- price[i]: i th day's stock price | ||
- to maximize profit, choose a single day to buy, and future day to sell. | ||
- return maximum profit | ||
- [7, 1, 5, 3, 6, 4] -> [0, 0, 4, 4, 5, 5] | ||
- [7, 6, 4, 3, 1] -> [0, 0, 0, 0, 0] | ||
2. strategy | ||
- profit = (sell price) - (buy price) | ||
3. complexity | ||
- time: O(N) | ||
- space: O(1) | ||
*/ | ||
int minPrice = prices[0]; | ||
for (int i = 0; i <prices.length; i++) { | ||
int tmp = prices[i]; | ||
if (i == 0) { | ||
prices[i] = 0; | ||
} else { | ||
prices[i] = Math.max(prices[i-1], prices[i] - minPrice); | ||
} | ||
minPrice = Math.min(minPrice, tmp); | ||
} | ||
|
||
return prices[prices.length - 1]; | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import java.util.*; | ||
|
||
public class Codec { | ||
/** | ||
1. complexity: | ||
- time: O(N * L), where N is the length of strs, L is maximum length of each word in strs | ||
- space: O(N * L) | ||
*/ | ||
|
||
// Encodes a list of strings to a single string. | ||
public String encode(List<String> strs) { | ||
// 필요한 정보: 전체 원본 문자열, 각 단어의 위치와 길이 | ||
StringBuilder origin = new StringBuilder(); | ||
StringJoiner meta = new StringJoiner("/"); | ||
StringJoiner encoded = new StringJoiner(";"); | ||
int startIdx = 0; | ||
for (String word: strs) { // O(N) | ||
origin.append(word); | ||
meta.add(String.format("(%d,%d)", startIdx, word.length())); | ||
startIdx += word.length(); | ||
} | ||
|
||
encoded.add(origin.toString()).add(meta.toString()); | ||
return encoded.toString(); | ||
} | ||
|
||
// Decodes a single string to a list of strings. | ||
public List<String> decode(String s) { | ||
List<String> ret = new ArrayList<>(); | ||
int delimeterIdx = s.lastIndexOf(";"); // O(N * L) | ||
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 commentThe reason will be displayed to describe this comment to others. Learn more. 음 일단 meta 정보를 뒤로 분리한 이유는, 본문과 meta 정보를 구분하는데에 위치 정보(처음 혹은 마지막)가 필수라고 생각해서였습니다! 말씀해주신대로 메타정보를 각 본문과 연결해 구현하는 방식이 가능하다면, 제가 구현한 방법이 메타 정보 문자열의 길이 만큼의 탐색이 추가로 필요한 비효율이 있는 것 같습니다! |
||
String origin = s.substring(0, delimeterIdx); // O(N * L) | ||
String meta = s.substring(delimeterIdx+1); // O(N * L) | ||
String[] wordInfos = meta.split("/"); | ||
for (String wordInfo: wordInfos) { // O(N) | ||
delimeterIdx = wordInfo.indexOf(","); // O(1) | ||
int length = Integer.parseInt(wordInfo.substring(delimeterIdx+1, wordInfo.length() - 1)); // O(1) | ||
String word = ""; | ||
if (length > 0) { | ||
int startIdx = Integer.parseInt(wordInfo.substring(1, delimeterIdx)); | ||
word = origin.substring(startIdx, startIdx + length); | ||
} | ||
ret.add(word); | ||
} | ||
return ret; | ||
} | ||
} | ||
|
||
// Your Codec object will be instantiated and called as such: | ||
// Codec codec = new Codec(); | ||
// codec.decode(codec.encode(strs)); | ||
|
||
|
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,37 @@ | ||||||||||||
class Solution { | ||||||||||||
public List<List<String>> groupAnagrams(String[] strs) { | ||||||||||||
/** | ||||||||||||
1. understanding | ||||||||||||
- grouping the anagrams together, and return groups | ||||||||||||
2. strategy | ||||||||||||
- anagram group's identity: same characters with same counts | ||||||||||||
- so, transform each strs to character and count hashtable, called 'id'. | ||||||||||||
- if groups contains strs's 'id', then append | ||||||||||||
- return values list | ||||||||||||
3. complexity | ||||||||||||
- time: O(N * L) where, N is the length of array strs, and L is the max length of each str | ||||||||||||
- space: O(N * L) | ||||||||||||
*/ | ||||||||||||
Map<Map<Character, Integer>, List<String>> groups = new HashMap<>(); | ||||||||||||
for (String word: strs) { | ||||||||||||
Map<Character, Integer> id = idOf(word); | ||||||||||||
List<String> group = groups.getOrDefault(id, new ArrayList<>()); | ||||||||||||
group.add(word); | ||||||||||||
groups.put(id, group); | ||||||||||||
} | ||||||||||||
|
||||||||||||
// System.out.println(groups); | ||||||||||||
List<List<String>> ret = new ArrayList<>(); | ||||||||||||
ret.addAll(groups.values()); | ||||||||||||
return ret; | ||||||||||||
Comment on lines
+23
to
+26
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. 요렇게 하시면 좀 더 깔끔할 것 같습니다.
Suggested change
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. 감사합니다 말씀해주신대로 입력파라미터 생성자로 처리하는게 코드 가독성이 좋을것 같네요 |
||||||||||||
} | ||||||||||||
|
||||||||||||
private Map<Character, Integer> idOf(String word) { | ||||||||||||
Map<Character, Integer> id = new HashMap<>(); | ||||||||||||
for (char c: word.toCharArray()) { | ||||||||||||
id.put(c, id.getOrDefault(c, 0) + 1); | ||||||||||||
} | ||||||||||||
return id; | ||||||||||||
} | ||||||||||||
} | ||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
class Trie { | ||
/** | ||
1. understanding | ||
- Trie data structure | ||
- To process at most 3 * 10^4 calls in proper time, each call must be under O(N), where N is the length of word. | ||
- insert: insert data into Trie | ||
- search: find data from inserted Datas | ||
- startsWith: find | ||
2. strategy | ||
- a) use list to save inserted words | ||
- insert: O(1) | ||
- search: O(L * N), where L is the length of list, N is the length of each words. | ||
- startsWith: O(L * N) | ||
Comment on lines
+11
to
+13
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.
|
||
- total call to be 3 * 10^4, i assume each method call count at most 10^4 or linear correlation in 10^4 scale. | ||
- so, L <= 10^4, N <= 10^4 | ||
- space: O(L * N) | ||
- it is enough to pass, but there are duplicates in space and also in excution count. | ||
- b) | ||
*/ | ||
|
||
private List<String> words; | ||
public Trie() { | ||
words = new ArrayList<>(); | ||
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 commentThe reason will be displayed to describe this comment to others. Learn more. 맞습니다! |
||
} | ||
|
||
public void insert(String word) { | ||
words.add(word); | ||
} | ||
|
||
public boolean search(String word) { | ||
for (String w: words) { | ||
if (w.equals(word)) return true; | ||
} | ||
return false; | ||
} | ||
|
||
public boolean startsWith(String prefix) { | ||
for (String w: words) { | ||
if (w.indexOf(prefix) == 0) return true; | ||
} | ||
return false; | ||
} | ||
} | ||
|
||
/** | ||
* 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); | ||
*/ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
class Solution { | ||
public boolean wordBreak(String s, List<String> wordDict) { | ||
/** | ||
1. understanding | ||
- check if s's segments are all in wordDict. | ||
- wordDict can be used multiple times | ||
2. strategy | ||
a) dynamic programming | ||
- dp[k]: substring(0,k+1) can be constructed by wordDict. | ||
- dp[0]: false | ||
- dp[1]: substring(0, 2) in wordDict | ||
- dp[k+1] = substring(0, k+2) in wordDict || Any(dp[k] && substring(k+1, k+2) in wordDict) | ||
- return dp[s.length()] | ||
3. complexity | ||
- time: O(N^2 * S), where N is the length of s, S is search time each segment in wordDict. You can calculate S in O(1) time, when change wordDict to Set. so O(N) is final time complexity. | ||
- space: O(N + W), W is the size of wordDict | ||
*/ | ||
Set<String> bow = new HashSet<>(wordDict); | ||
boolean[] dp = new boolean[s.length() + 1]; | ||
|
||
for (int i = 1; i < dp.length; i++) { // O(N) | ||
String segment = s.substring(0, i); | ||
dp[i] = bow.contains(segment); | ||
for (int j = 0; j < i; j++) { // O(N) | ||
if (dp[i]) break; | ||
segment = s.substring(j, i); | ||
dp[i] = dp[i] || (dp[j] && bow.contains(segment)); // O(1) | ||
} | ||
} | ||
|
||
return dp[s.length()]; | ||
} | ||
} | ||
|
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.
입력 배열을 변경하셨군요. 신선한 접근입니다!
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.
넵 이 문제는 추가 공간 할당 없이 처리 가능하더라구요 😀