Skip to content

[geegong] Week 02 solutions #1751

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
Aug 3, 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
82 changes: 82 additions & 0 deletions 3sum/Geegong.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import java.util.*;

public class Geegong {

/**
* Time complexity : O(n^2)
* space complexity : O(n^2)
* @param nums
* @return
*/
public List<List<Integer>> threeSum(int[] nums) {

// 중복되는 값은 없어야 하기에 HashSet 으로 result
HashSet<List<Integer>> result = new HashSet<>();
Copy link
Contributor

Choose a reason for hiding this comment

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

3sum의 문제의 포인트는 중복된 값을 필터링 하는게 주요한 요소라고 생각했는 데, hashMap을 사용해서 중복 값을 필터링한 부분이 굉장히 인상적이네요.


// Key : 배열 원소 , value : List<String> 인덱스들
// elementMap 은 two pointer 의 값을 더한 값에서 0이 되기 위한 요소를 찾기위해 사용될 것임
// tc : O(n)
Comment on lines +16 to +18
Copy link
Contributor

Choose a reason for hiding this comment

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

상세한 주석 및 시간 복잡도 계산 좋습니다.

Map<Integer, List<Integer>> elementMap = new HashMap<>();
for (int index = 0; index<nums.length; index++) {
int value = nums[index];
if (elementMap.containsKey(value)) {
List<Integer> indices = elementMap.get(value);
indices.add(index);
elementMap.put(value, indices);
} else {
List<Integer> newIndices = new ArrayList<>();
newIndices.add(index);
elementMap.put(value, newIndices);
}
}

// leftIndex : 0에서 부터 시작하는 index
// rightIndex : nums.length - 1에서부터 감소하는 index
// leftIndex > rightIndex 되는 순간까지만 for문을 돌 것이다.
// tc : O(N^2 / 2)
Copy link
Contributor

@jangwonyoon jangwonyoon Aug 2, 2025

Choose a reason for hiding this comment

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

시간 복잡도에서 / 2 는 큰 의미가 없어보여요. 결국에는 동일한 tc: O(N^2)인데 어떻게 생각하시나요??

Copy link
Contributor Author

Choose a reason for hiding this comment

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

시간 복잡도에서 / 2 는 큰 의미가 없어보여요. 결국에는 동일한 tc: O(N^2)인데 어떻게 생각하시나요??

네넵, 맞습니다~ 말씀하신것 처럼 n^2 인데 루프가 반으로 나눠져서 그만 저렇게 적어버렸네요 ^^;;
꼼꼼한 확인 감사드려요~~ 👍

for (int leftIndex=0; leftIndex < nums.length; leftIndex++) {
for (int rightIndex=nums.length - 1; rightIndex >= 0; rightIndex--) {

if (leftIndex >= rightIndex) {
break;
}


int leftValue = nums[leftIndex];
int rightValue = nums[rightIndex];

int neededValueToZero = -leftValue - rightValue;
if (elementMap.containsKey(neededValueToZero)) {
// elementMap의 value 가 leftIndex, rightIndex 은 아닌지 확인

List<Integer> indices = elementMap.get(neededValueToZero);
// zero 를 만들 수 있는 세번쨰 인덱스가 있는지 확인
int thirdIndex = findThirdIndexToBeZero(leftIndex, rightIndex, indices);
if (-1 != thirdIndex) {
List<Integer> newOne = new ArrayList<>();
newOne.add(nums[leftIndex]);
newOne.add(nums[rightIndex]);
newOne.add(nums[thirdIndex]);
result.add(newOne.stream().sorted().toList());
Copy link
Contributor

Choose a reason for hiding this comment

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

현재 for문 내부에서, List를 정렬을 매번해서 연산을 진행하는 데, 이는 불필요한 연산 낭비로 보여요.

처음부터 two pointer 알고리즘을 떠올려서 정렬 + 투포인터 접근으로 한다면, 연산을 줄일수있을거 같은데 어떻게 생각하실까요??

Copy link
Contributor Author

Choose a reason for hiding this comment

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

오오.. 미리 nums 를 정렬해서 two pointer 로 돌린다면 마찬가지로 result 에 중복되는게 있는지 체크를 해야되지 않을까 싶은 생각도 드는데 🧐
아니면 아래처럼 중복되는걸 미리 체크하는것도 할 수 있지 않을까 싶은데..
newOne 라는 list 를 만들어서 각 원소들을 add 하는건 해야되지만 newOne.sorted() 처리는 안해도 되겠네용👍

List<Integer> newOne = new ArrayList<>();
                        newOne.add(nums[leftIndex]);
                        newOne.add(nums[rightIndex]);
                        newOne.add(nums[thirdIndex]);
if (!result.contains(newOne)) {
     result.add(newOne);
}

}

}

}
}

return result.stream().toList();

}

public int findThirdIndexToBeZero(int leftIndex, int rightIndex, List<Integer> indices) {
for (int index : indices) {
if (index != leftIndex && index != rightIndex) {
return index;
}
}

return -1;
}
}

4 changes: 4 additions & 0 deletions house-robber/Geegong.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
public class Geegong {
// 이 문제는 시간이 남을때 풀 예정 😅
}

51 changes: 51 additions & 0 deletions product-of-array-except-self/Geegong.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import java.util.Arrays;

public class Geegong {

/**
* Time complexity : O(n)
* Space complexity : O(1) (except result)
*
* 풀이 : prefix array , suffix array 를 각 배열마다 구하여 각 array에 해당되는 인덱스의 값들을 곱하여 결과값을 도출
*
* @param nums
* @return
*/
public int[] productExceptSelf(int[] nums) {

int[] result = new int[nums.length];

// 1. result 는 먼저 prefix 배열들의 곱으로 채운다.
// ( prefix 배열이란 해당되는 index 이전의 배열요소값들을 의미)

// 앞에서부터 누적되는 총 곱의 값
int accumulatedProduct = 1;
for (int index=0; index<nums.length; index++) {
if (index == 0) {
result[index] = 1;
continue;
}

result[index] = accumulatedProduct * nums[index - 1];
accumulatedProduct = result[index];
}
Comment on lines +23 to +31
Copy link
Contributor

Choose a reason for hiding this comment

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

 for (int i = 0; i < nums.length; i++) {
        result[i] = prefixProduct;
        prefixProduct *= nums[i];
    }

위와 같은 방식으로 들여쓰기를 하면, 가독성 측면에서 더욱 좋을거 같습니다.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

헉 천재이십니다👍👍
전 너무 제 생각대로 코드를 짠거 같아 부끄럽네요ㅋㅋ


// 2. 배열의 뒤에서부터 product of suffix 값은 result 배열 하나하나에 대체한다.

// nums 배열 안에서 뒤에서부터 누적되는 총 곱의 값
accumulatedProduct = 1;
for (int index=nums.length - 1; index >= 0; index--) {
if (index == nums.length - 1) {
accumulatedProduct = nums[index];
continue;
}

result[index] = result[index] * accumulatedProduct;
accumulatedProduct = accumulatedProduct * nums[index];
}

return result;
}

}