Skip to content

[minji-go] week 06 solutions #1428

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 12 commits into from
May 10, 2025
36 changes: 18 additions & 18 deletions combination-sum/minji-go.java
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
/*
Problem: https://leetcode.com/problems/combination-sum/
Description: return a list of all unique combinations of candidates where the chosen numbers sum to target
Concept: Array, Backtracking
Time Complexity: O(Nᵀ), Runtime 2ms
Space Complexity: O(T), Memory 44.88MB
*/
class Solution {
public List<List<Integer>> answer = new ArrayList<>();
/**
* <a href="https://leetcode.com/problems/combination-sum/">week03-3.combination-sum</a>
* <li>Description: return a list of all unique combinations of candidates where the chosen numbers sum to target </li>
* <li>Topics: Array, Backtracking </li>
* <li>Time Complexity: O(K^T), Runtime 2ms </li>
* <li>Space Complexity: O(T), Memory 44.9MB </li>
*/

class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> combinations = new ArrayList<>();
Arrays.sort(candidates);
findCombination(candidates, target, new ArrayList<>(), 0);
return answer;
dfs(candidates, target, 0, new ArrayList<>(), combinations);
return combinations;
}

public void findCombination(int[] candidates, int target, List<Integer> combination, int idx) {
if(target == 0) {
answer.add(new ArrayList<>(combination));
public void dfs(int[] candidates, int target, int index, List<Integer> combination, List<List<Integer>> combinations) {
if (target == 0) {
combinations.add(new ArrayList<>(combination));
return;
}

for(int i=idx; i<candidates.length; i++) {
if(candidates[i] > target) break;
for (int i = index; i < candidates.length; i++) {
if (target - candidates[i] < 0) break;

combination.add(candidates[i]);
findCombination(candidates, target-candidates[i], combination, i);
combination.remove(combination.size()-1);
dfs(candidates, target - candidates[i], i, combination, combinations);
combination.remove(combination.size() - 1);
}
}
}
28 changes: 28 additions & 0 deletions container-with-most-water/minji-go.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* <a href="https://leetcode.com/problems/container-with-most-water/">week06-2.container-with-most-water</a>
* <li>Description: Return the maximum amount of water a container can store</li>
* <li>Topics: Array, Two Pointers, Greedy </li>
* <li>Time Complexity: O(N), Runtime 5ms </li>
* <li>Space Complexity: O(1), Memory 57.42MB </li>
*/
class Solution {
public int maxArea(int[] height) {
int maxArea = 0;
int left = 0;
int right = height.length - 1;

while (left < right) {
int width = right - left;
int minHeight = Math.min(height[left], height[right]);
maxArea = Math.max(maxArea, width * minHeight);

if (height[left] < height[right]) {
left++;
} else {
right--;
}
}

return maxArea;
}
}
48 changes: 27 additions & 21 deletions decode-ways/minji-go.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
/*
Problem: https://leetcode.com/problems/decode-ways/
Description: Given a string s containing only digits, return the number of ways to decode it
Concept: String, Dynamic Programming
Time Complexity: O(N), Runtime 1ms
Space Complexity: O(N), Memory 42.12MB
*/
/**
* <a href="https://leetcode.com/problems/decode-ways/">week03-5.decode-ways</a>
* <li>Description: return the number of ways to decode it </li>
* <li>Topics: String, Dynamic Programming </li>
* <li>Time Complexity: O(N), Runtime 1ms </li>
* <li>Space Complexity: O(1), Memory 41.8MB</li>
*/
class Solution {
public int numDecodings(String s) {
int[] dp = new int[s.length()];
if(decode(s.substring(0, 1))) dp[0]=1;
if(s.length()>1 && decode(s.substring(1, 2))) dp[1]+=dp[0];
if(s.length()>1 && decode(s.substring(0, 2))) dp[1]+=dp[0];
if (s.charAt(0) == '0') {
return 0;
}

int last2 = 1;
int last1 = 1;

for (int i = 1; i < s.length(); i++) {
int curr = 0;
if (s.charAt(i) != '0') {
curr += last1;
}

for(int i=2; i<s.length(); i++){
if(decode(s.substring(i,i+1))) dp[i]+=dp[i-1];
if(decode(s.substring(i-1,i+1))) dp[i]+=dp[i-2];
int num = Integer.parseInt(s.substring(i - 1, i + 1));
if (num >= 10 && num <= 26) {
curr += last2;
}

last2 = last1;
last1 = curr;
}
return dp[s.length()-1];
}

public boolean decode(String s){
int num = Integer.parseInt(s);
int numLength = (int) Math.log10(num) + 1;
if(num<0 || num>26 || numLength != s.length()) return false;
return true;
return last1;
}
}
69 changes: 69 additions & 0 deletions design-add-and-search-words-data-structure/minji-go.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* <a href="https://leetcode.com/problems/design-add-and-search-words-data-structure/">week06-3.design-add-and-search-words-data-structure</a>
* <li>Description: Design a data structure that supports adding new words and finding if a string matches any previously added string</li>
* <li>Topics: String, Depth-First Search, Design, Trie </li>
* <li>Time Complexity: O(N), Runtime 274ms </li>
* <li>Space Complexity: O(N), Memory 118.44MB </li>
*/
class WordDictionary {
private Trie dictionary;

public WordDictionary() {
dictionary = new Trie();
}

public void addWord(String word) {
dictionary.add(word);
}

public boolean search(String word) {
return dictionary.contains(word);
}

}

public class Trie {
private boolean isEnd;
private Map<Character, Trie> next;

Trie() {
next = new HashMap<>();
}

public void add(String word) {
Trie trie = this;
for(char c : word.toCharArray()){
trie = trie.next.computeIfAbsent(c, k -> new Trie());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

computeIfAbsent메서드는 Map자료구조에 기본으로 있는 요소인가 보군요..!
메서드 호출부에 전달되는 함수의 c, k 에서 c 는 for loop에서 참조되는 char 변수가 맞나요?

k 는 뭔지 궁금합니다..!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안녕하세요 😁

computeIfAbsent 메서드는 첫 번째 매개변수로 Map의 key를 전달받고,
두 번째 매개변수로는 해당 key가 존재하지 않을 경우, 생성할 값을 정의하는 mappingFunction을 전달받습니다.

여기서는 첫 번째 매개변수 c는 말씀하신대로 루트 변수입니다 👍
두 번째 매개변수의 k는 이 c 값을 전달받아 new Trie()를 생성하고, k를 키로 하여 Map에 추가하는 역할을 합니다!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

설명 감사합니다! 이번주도 수고 많으셨습니다 :)

}
trie.isEnd = true;
}

public boolean contains(String word) {
Trie trie = this;
for(int i=0; i<word.length(); i++){
char c = word.charAt(i);
if(c == '.') {
for(Trie newTrie : trie.next.values()) {
if(newTrie.contains(word.substring(i+1))){
return true;
}
}
return false;
} else {
trie = trie.next.get(c);
if(trie == null) {
return false;
}
}
}

return trie.isEnd;
}
}

/**
* Your WordDictionary object will be instantiated and called as such:
* WordDictionary obj = new WordDictionary();
* obj.addWord(word);
* boolean param_2 = obj.search(word);
*/
28 changes: 28 additions & 0 deletions longest-increasing-subsequence/minji-go.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* <a href="https://leetcode.com/problems/longest-increasing-subsequence/">week06-4.longest-increasing-subsequence</a>
* <li>Description: return the length of the longest strictly increasing subsequence</li>
* <li>Topics: Array, Binary Search, Dynamic Programming </li>
* <li>Time Complexity: O(NLogN), Runtime 6ms </li>
* <li>Space Complexity: O(N), Memory 44.3MB </li>
*/
class Solution {
public int lengthOfLIS(int[] nums) {
List<Integer> lisTails = new ArrayList<>();

for(int num : nums){
int idx = Collections.binarySearch(lisTails, num);

if(idx < 0) {
idx = -idx -1;
}

if(idx == lisTails.size()) {
lisTails.add(num);
} else {
lisTails.set(idx, num);
}
}

return lisTails.size();
}
}
17 changes: 17 additions & 0 deletions number-of-1-bits/minji-go.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* <a href="https://leetcode.com/problems/number-of-1-bits/">week03-2.number-of-1-bits</a>
* <li>Description: returns the number of set bits in its binary representation</li>
* <li>Topics: Divide and Conquer, Bit Manipulation </li>
* <li>Time Complexity: O(logN), Runtime 0ms </li>
* <li>Space Complexity: O(1), Memory 41.95MB </li>
*/
class Solution {
public int hammingWeight(int n) {
int count = 0;
while(n != 0) {
n &= (n-1);
count++;
}
return count;
}
}
43 changes: 43 additions & 0 deletions spiral-matrix/minji-go.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* <a href="https://leetcode.com/problems/spiral-matrix/">week06-5.spiral-matrix</a>
* <li>Description: return all elements of the matrix in spiral order</li>
* <li>Topics: Array, Matrix, Simulation </li>
* <li>Time Complexity: O(N*M), Runtime 0ms </li>
* <li>Space Complexity: O(1), Memory 41.95MB </li>
*/
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> answer = new ArrayList<>();
int lr = 0;
int hr = matrix.length - 1;
int lc = 0;
int hc = matrix[0].length - 1;

while (lr <= hr && lc <= hc) {
for (int c = lc; c <= hc; c++) {
answer.add(matrix[lr][c]);
}
lr++;

for (int r = lr; r <= hr; r++) {
answer.add(matrix[r][hc]);
}
hc--;

if (lr <= hr) {
for (int c = hc; c >= lc; c--) {
answer.add(matrix[hr][c]);
}
hr--;
}

if (lc <= hc) {
for (int r = hr; r >= lr; r--) {
answer.add(matrix[r][lc]);
}
lc++;
}
}
return answer;
}
}
51 changes: 36 additions & 15 deletions valid-palindrome/minji-go.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,43 @@
/*
Problem: https://leetcode.com/problems/valid-palindrome/
Description: return true if it is a palindrome, alphanumeric characters(letters and numbers) reads the same forward and backward
Concept: Two Pointers, String
Time Complexity: O(n), Runtime: 10ms
Space Complexity: O(n), Memory: 58.6MB
*/
/**
* <a href="https://leetcode.com/problems/valid-palindrome/">week03-1.valid-palindrome</a>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이전 주차에 풀어보셨던 걸 (코드 정리 겸) 다시 풀어보신걸까요?

+) 요건 알고리즘 내용하고 무관한(?) 내용인데, 뭔가 html 태그로 주석을 남겨놓으셔서,,, 요고는 별도로 블로그 포스팅 하는 용도로 하신 건지 궁금합니다!!

Copy link
Contributor Author

@minji-go minji-go May 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3기 참여할 때 풀었었는데, 4기 때는 안해서 다시 풀어봤습니다😂
리뷰해주셔서 감사합니다!! 제 코드지만 다시보면 낯선부분도 있어서 도움이 많이 되네요 👍

+) html 주석 넣은건, ide에서 javadoc 형식으로 보는게 좋아서 그렇게 표기했습니다 ㅎㅎ
image

* <li>Description: return true if it is a palindrome </li>
* <li>Topics: Two Pointers, String </li>
* <li>Time Complexity: O(N), Runtime 2ms </li>
* <li>Space Complexity: O(1), Memory 42.75MB </li>
*/
class Solution {
public boolean isPalindrome(String s) {
String regex ="[^A-Za-z0-9]";
String palindrome = s.replaceAll(regex,"").toLowerCase(); //replaceAll(), toLowerCase(): O(n)
int left = 0;
int right = s.length() - 1;

boolean answer = true;
for(int i=0; i<palindrome.length()/2; i++){
if(palindrome.charAt(i) != palindrome.charAt(palindrome.length()-1-i)) {
answer = false;
break;
while (left < right) {
char charLeft = s.charAt(left);
char charRight = s.charAt(right);
if (isNotValidCharacter(charLeft)) {
left++;
continue;
}
if (isNotValidCharacter(charRight)) {
right--;
continue;
}

if (Character.toLowerCase(charLeft) != Character.toLowerCase(charRight)) {
return false;
}
left++;
right--;
}
return true;

}

private boolean isNotValidCharacter(char c) {
if ((c >= '0' && c <= '9')
|| (c >= 'a' && c <= 'z')
|| (c >= 'A' && c <= 'Z')) {
return false;
}
return answer;
return true;
}
}
36 changes: 36 additions & 0 deletions valid-parentheses/minji-go.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* <a href="https://leetcode.com/problems/valid-parentheses/">week06-1.valid-parentheses</a>
* <li>Description: determine if the input string is valid </li>
* <li>Topics: String, Stack </li>
* <li>Time Complexity: O(N), Runtime 2ms </li>
* <li>Space Complexity: O(N), Memory 41.98MB </li>
*/

class Solution {
public boolean isValid(String s) {
Deque<Character> stack = new ArrayDeque<>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stack 말고 Deque를 사용하셨던 특별한 이유가 있었는지 궁금합니다..!
특정 연산( push , pop) 같은게 좀더 빠른 구석이 있나요?

Copy link
Contributor Author

@minji-go minji-go May 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stack은 Vector 클래스를 상속받고 있고, ArrayDeque는 내부적으로 배열을 사용하고 있습니다.
Vector는 모든 메서드가 synchronized로 되어 있어서 멀티스레드 환경이 아닌 경우엔 ArrayDeque가 성능상 좋다고 합니다!

ref. https://docs.oracle.com/javase/8/docs/api/java/util/ArrayDeque.html

for(char c : s.toCharArray()) {
if(isOpenBracket(c)){
stack.push(c);
continue;
}

if(stack.isEmpty() || isNoneMatchBracket(stack.pop(), c)) {
return false;
}
}

return stack.isEmpty();
}

private boolean isOpenBracket(char open) {
return open == '(' || open == '{' || open == '[';
}

private boolean isNoneMatchBracket(char open, char close) {
if(open == '(') return close != ')';
if(open == '{') return close != '}';
if(open == '[') return close != ']';
return true;
}
}