Skip to content
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> dp = new ArrayList<>();

for(int num : nums){
int idx = Collections.binarySearch(dp, num);
Copy link
Contributor

Choose a reason for hiding this comment

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

오! Collections에서 이진탐색도 가능한가보네요! 저는 항상 sort만 썼었는데..!🤣

덕분에 좋은것(?) 많이 배워갑니다. 감사합니다!

Copy link
Contributor

Choose a reason for hiding this comment

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

오..? 그런데 코드를 보다보니 제가 일반적으로 봐왔던 dp하고는 뭔가 다른 느낌이 오는것 같아서요..!
혹시 괜찮으시다면 알고리즘의 흐름을 간략하게 설명해주실 수 있을까요?? (뭔가 이해는 안되지만 나이스해 보여서,,, 배우고싶습니다!)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

dp라는 변수명이 다소 적절하지 않았던 것 같아요. 실제로는 “정렬된 숫자 배열”에 더 가까운 역할이라 sortedNums처럼 이름을 바꾸면 더 명확할 것 같아요.

이 알고리즘은 nums 배열을 순회하면서 각 숫자가 들어갈 정렬된 위치를 이진 탐색으로 찾아내고, 해당 위치에 더 큰 값이 있었다면 덮어써서 더 긴 증가 수열을 만들 수 있도록 하는 방식입니다!

저도 이번에 Collections.binarySearch()를 처음 알게 되었는데요,
binarySearch(dp, num)은 dp 리스트에서 num을 찾아서 존재하면 해당 인덱스를, 존재하지 않으면 삽입해야 할 위치를 -index - 1 형식으로 음수로 반환합니다.

예를 들어, 삽입해야 할 위치가 0이라면 단순히 -0이면 0이 되어버리니,
실제 찾은 경우와 구분하기 위해 -(삽입위치 + 1)을 반환하는 방식이에요 ☀️

이해가 되셨을지 모르겠네요...! 😅 코드 리뷰 감사합니다! 🥰


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

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

return dp.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;
}
}
39 changes: 39 additions & 0 deletions spiral-matrix/minji-go.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* <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 && lr<=hr; c++) {
Copy link
Contributor

Choose a reason for hiding this comment

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

lr <= hr 조건은 이미 while 루프에서 체크했으니까, 내부 반복문에서 다시 확인할 필요 없을 것 같아요. 😄

answer.add(matrix[lr][c]);
}
lr++;

for(int r=lr; r<=hr && lc<=hc; r++) {
Copy link
Contributor

Choose a reason for hiding this comment

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

앞서 lr 값은 업데이트됐지만, lc <= hc 조건은 이미 while 루프에서 체크했으니까, 내부 반복문에서 다시 확인할 필요 없을 것 같아요. 😄

answer.add(matrix[r][hc]);
}
hc--;

for(int c=hc; c>=lc && lr<=hr; c--){
Copy link
Contributor

Choose a reason for hiding this comment

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

위에서 lr 값이 업데이트 되었으므로, lr <= hr 조건을 먼저 체크한 후에 반복문을 진행하고, 그 후에 hr 값을 업데이트해야 할 것 같습니다.

answer.add(matrix[hr][c]);
}
hr--;

for(int r=hr; r>=lr && lc<=hc; r--){
Copy link
Contributor

Choose a reason for hiding this comment

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

위에서 hc 값이 업데이트 되었으므로, lc<=hc 조건을 먼저 체크한 후에 반복문을 진행하고, 그 후에 lc 값을 업데이트해야 할 것 같습니다.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

안녕하세요!
체크 과정이 루프마다 달라지는게 번잡한 거 같아서 유사한 패턴으로 넣어봤는데, 불필요한 동작일 수 있겠네요!

리뷰 감사합니다 👍

answer.add(matrix[r][lc]);
}
lc++;
}
return answer;
}
}
27 changes: 12 additions & 15 deletions valid-palindrome/minji-go.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
/*
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 13ms </li>
* <li>Space Complexity: O(N), Memory 45.55MB </li>
*/
class Solution {
public boolean isPalindrome(String s) {
String regex ="[^A-Za-z0-9]";
String palindrome = s.replaceAll(regex,"").toLowerCase(); //replaceAll(), toLowerCase(): O(n)
String str = s.toLowerCase().replaceAll("[^0-9a-z]", "");
Copy link
Contributor

Choose a reason for hiding this comment

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

현재는 새로운 문자열을 생성하기 때문에 공간 복잡도가 O(n)이지만, 투 포인터 방식으로 접근하면 추가 공간 없이 O(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;
for (int i = 0; i < str.length() / 2; i++) {
if (str.charAt(i) != str.charAt(str.length() - 1 - i)) {
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;
}
}