Skip to content

Commit 43fe332

Browse files
authored
Merge branch 'DaleStudy:main' into main
2 parents 116ad02 + 4c8b68f commit 43fe332

File tree

449 files changed

+14384
-9
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

449 files changed

+14384
-9
lines changed

.github/labeler.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,8 @@ elixir:
5252
- changed-files:
5353
- any-glob-to-any-file:
5454
- "**/*.exs"
55+
56+
rust:
57+
- changed-files:
58+
- any-glob-to-any-file:
59+
- "**/*.rs"

.github/pull_request_template.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
## 답안 제출 문제
22

33
<!--
4-
자신의 수준이나 일정에 맞게 금주에 푸시기로 정한 문제들만 나열해주세요.
5-
코드 검토자들이 PR 승인 여부를 결정할 때 도움이 됩니다.
4+
자신의 수준이나 일정에 맞게 👉금주에 푸시기로 정한 문제들👈만 나열해주세요.
5+
리뷰어들이 검토와 PR 승인 여부를 결정할 때 도움이 됩니다.
66
-->
77

88
- [ ] 문제 1
99
- [ ] 문제 2
1010
- [ ] 문제 3
11+
<!-- - [ ] 문제 4 풀고싶지 않은 문제는 이렇게 주석처리 해 주셔도 좋아요 -->
1112

1213
## 체크 리스트
1314

14-
- [ ] PR을 프로젝트에 추가하고 Week를 현재 주차로 설정해주세요.
15+
- [ ] 우측 메뉴에서 PR을 **Projects**에 추가해주세요.
16+
- [ ] **Projects**의 오른쪽 버튼(▼)을 눌러 확장한 뒤, **Week**를 현재 주차로 설정해주세요.
1517
- [ ] 바로 앞에 PR을 열어주신 분을 코드 검토자로 지정해주세요.
16-
- [ ] 문제를 모두 푸시면 프로젝트에서 Status를 `In Review`로 설정해주세요.
18+
- [ ] 문제를 모두 푸시면 프로젝트에서 **Status** `In Review`로 설정해주세요.
1719
- [ ] 코드 검토자 1분 이상으로부터 승인을 받으셨다면 PR을 병합해주세요.

.github/workflows/integration.yaml

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,19 @@ jobs:
1515
- name: Get PR labels
1616
id: pr-labels
1717
run: |
18+
echo "🔍 PR 번호: ${{ github.event.pull_request.number }}"
1819
pr_number="${{ github.event.pull_request.number }}"
20+
21+
echo "📋 PR 라벨 조회 중..."
1922
labels_json=$(gh pr view $pr_number --json labels -q '.labels[].name')
23+
echo "확인된 라벨: $labels_json"
24+
2025
if [ -n "$labels_json" ]; then
21-
echo "has_maintenance=$(echo $labels_json | grep -q 'maintenance' && echo 'true' || echo 'false')" >> $GITHUB_OUTPUT
26+
has_maintenance=$(echo $labels_json | grep -q 'maintenance' && echo 'true' || echo 'false')
27+
echo "maintenance 라벨 포함 여부: $has_maintenance"
28+
echo "has_maintenance=$has_maintenance" >> $GITHUB_OUTPUT
2229
else
30+
echo "maintenance 라벨이 없는 PR입니다. 파일명 규칙 검사를 진행합니다."
2331
echo "has_maintenance=false" >> $GITHUB_OUTPUT
2432
fi
2533
env:
@@ -28,35 +36,46 @@ jobs:
2836
# 줄바꿈 체크
2937
- name: Check for missing end line breaks
3038
run: |
31-
# 따옴표를 제거하고 파일 목록 가져오기
39+
echo "🔍 줄바꿈 검사 시작"
40+
echo "기준 커밋: ${{ github.event.pull_request.base.sha }}"
41+
echo "현재 커밋: ${{ github.sha }}"
42+
3243
files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | tr -d '"')
3344
success=true
3445
35-
echo "변경된 파일 목록:"
46+
echo "📝 변경된 파일 목록:"
3647
echo "$files"
3748
3849
echo "## 줄바꿈 누락 파일" >> $GITHUB_STEP_SUMMARY
3950
for file in $files; do
51+
echo "검사 중: $file"
4052
if [ -s "$file" ] && [ "$(tail -c 1 $file | wc -l)" -eq 0 ]; then
41-
echo "발견된 줄바꿈 누락: $file"
53+
echo " 줄바꿈 누락: $file"
4254
echo "- $file" >> $GITHUB_STEP_SUMMARY
4355
success=false
56+
else
57+
echo "✅ 정상: $file"
4458
fi
4559
done
4660
4761
if [ "$success" = false ]; then
62+
echo "⚠️ 줄바꿈 검사 실패"
4863
echo -e "\n:warning: 파일 끝의 누락된 줄바꿈을 추가해 주세요." >> $GITHUB_STEP_SUMMARY
4964
exit 1
65+
else
66+
echo "✅ 모든 파일의 줄바꿈 정상"
5067
fi
5168
5269
# 제어문자 체크
5370
- name: Check for control characters in filenames
5471
run: |
72+
echo "🔍 파일명 제어문자 검사 시작"
5573
files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | tr -d '"')
5674
success=true
5775
5876
echo "## 제어문자가 포함된 파일명" >> $GITHUB_STEP_SUMMARY
5977
for file in $files; do
78+
echo "검사 중: $file"
6079
# basename으로 파일명만 추출하고 따옴표 제거
6180
filename=$(basename "$file" | tr -d '"')
6281
@@ -71,43 +90,66 @@ jobs:
7190
7291
# 이스케이프 시퀀스 체크
7392
[[ "$filename" =~ (\\[0-7]{1,3}|\\x[0-9a-fA-F]{1,2}) ]]; then
93+
echo "❌ 제어문자 발견: $file"
7494
echo "- $file (제어문자 포함)" >> $GITHUB_STEP_SUMMARY
7595
success=false
96+
else
97+
echo "✅ 정상: $file"
7698
fi
7799
done
78100
79101
if [ "$success" = false ]; then
102+
echo "⚠️ 제어문자 검사 실패"
80103
echo -e "\n:warning: 파일명에서 제어문자를 제거해 주세요." >> $GITHUB_STEP_SUMMARY
81104
exit 1
105+
else
106+
echo "✅ 모든 파일명이 제어문자 없이 정상"
82107
fi
83108
84109
# 파일명 규칙 체크 - maintenance 라벨이 없는 경우에만 실행
85110
- name: Check filename rules
86111
if: ${{ steps.pr-labels.outputs.has_maintenance != 'true' }}
87112
run: |
88-
files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | tr -d '"')
113+
echo "🔍 파일명 규칙 검사 시작"
114+
echo "PR 작성자: ${{ github.event.pull_request.user.login }}"
115+
116+
# PR의 공통 조상 커밋을 찾아서 merge base로 설정
117+
merge_base=$(git merge-base ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }})
118+
echo "Merge base 커밋: $merge_base"
119+
120+
files=$(git diff --name-only $merge_base ${{ github.event.pull_request.head.sha }} | tr -d '"')
89121
pr_author="${{ github.event.pull_request.user.login }}"
90122
success=true
91123
124+
echo "📝 검사할 파일 목록:"
125+
echo "$files"
126+
92127
echo "## 파일명 규칙 위반" >> $GITHUB_STEP_SUMMARY
93128
for file in $files; do
94129
if [ -f "$file" ]; then
95130
131+
echo "검사 중: $file"
96132
# 파일명만 추출 (경로 제외)
97133
filename=$(basename "$file")
98134
99135
# 파일명이 GitHub계정명인지 확인
100136
shopt -s nocasematch
101137
if [[ ! "$filename" = "$pr_author"* ]]; then
138+
echo "❌ 규칙 위반: $file"
102139
echo "- $file" >> $GITHUB_STEP_SUMMARY
103140
success=false
141+
else
142+
echo "✅ 정상: $file"
104143
fi
105144
fi
106145
done
107146
108147
if [ "$success" = false ]; then
148+
echo "⚠️ 파일명 규칙 검사 실패"
109149
echo -e "\n:warning: 파일명은 반드시 'GitHub계정명' 또는 'GitHub계정명-xxx' 형식으로 해주셔야 합니다. (예: ${pr_author}.ts, ${pr_author}-1.ts, ${pr_author}-2.ts)" >> $GITHUB_STEP_SUMMARY
110150
exit 1
151+
else
152+
echo "✅ 모든 파일명이 규칙에 맞게 정상"
111153
fi
112154
env:
113155
GH_TOKEN: ${{ github.token }}

3sum/Chaedie.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
"""
2+
첫번째 풀이 -> 달레의 코드 풀이
3+
1) sort와 two pointer를 활용한 풀이
4+
2) has_set 을 활용한 중복 제거
5+
6+
두번째 풀이 -> Neetcode 풀이
7+
1) sort와 two pointer를 활용한 풀이
8+
2) while loop 를 활용한 중복 제거
9+
10+
Time: O(n^2) = O(n) * O(n)
11+
Space: O(n)
12+
"""
13+
14+
15+
class Solution:
16+
def threeSum(self, nums: List[int]) -> List[List[int]]:
17+
nums.sort()
18+
res = set()
19+
n = len(nums)
20+
21+
for i in range(n):
22+
l, r = i + 1, n - 1
23+
while l < r:
24+
summ = nums[i] + nums[l] + nums[r]
25+
if summ < 0:
26+
l += 1
27+
elif summ > 0:
28+
r -= 1
29+
else:
30+
res.add((nums[i], nums[l], nums[r]))
31+
l += 1
32+
return list(res)
33+
34+
35+
class Solution:
36+
def threeSum(self, nums: List[int]) -> List[List[int]]:
37+
nums.sort()
38+
res = []
39+
n = len(nums)
40+
41+
for i in range(n):
42+
l, r = i + 1, n - 1
43+
44+
if i > 0 and nums[i] == nums[i - 1]:
45+
continue
46+
47+
while l < r:
48+
summ = nums[i] + nums[l] + nums[r]
49+
if summ < 0:
50+
l += 1
51+
elif summ > 0:
52+
r -= 1
53+
else:
54+
res.append([nums[i], nums[l], nums[r]])
55+
l += 1
56+
while nums[l] == nums[l - 1] and l < r:
57+
l += 1
58+
59+
return res

3sum/EcoFriendlyAppleSu.kt

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package leetcode_study
2+
3+
/**
4+
* 주어진 배열의 세 원소의 합이 0인 경우를 구하는 문제. (세 개의 값의 결과는 중복되지 않음)
5+
*
6+
* 주어진 조건
7+
* 3 <= nums.length <= 3000
8+
* -105 <= nums[i] <= 105
9+
*/
10+
11+
/**
12+
* case01. 조합을 사용한 풀이.
13+
* 시간 초과 발생 이유
14+
* -> 모든 가능한 세 개의 조합을 생성하기 때문에 발생.
15+
* 시간 복잡도:
16+
* -> 세 개의 조합 생성 과정: O(n * (n-1) * (n-2)) / 3. 최악의 경우 n = 3000, 4.5 억개 조합 생성
17+
* -> 세 개의 조합 결과 sorting 과정: O(klogk). k = 3
18+
* -> 결과값을 필터링해 합이 0인 배열을 필터하는 과정: O(n)
19+
* 나머지 연산이 세 개의 조합 생성 과정에 영향을 받아 계산 횟수 증가.
20+
*
21+
* 공간 복잡도:
22+
* -> 각 조합을 모두 저장: O(n^3)
23+
*/
24+
fun threeSumUseCombination(nums: IntArray): List<List<Int>> {
25+
// 결과를 담을 Set 자료구조
26+
val processResult = mutableSetOf<List<Int>>()
27+
28+
// 주어진 배열의 크기를 담는 변수
29+
val maxNumber = nums.size
30+
31+
// 조합 배열의 크기
32+
val givenSize = 3
33+
34+
// 나타낼 인덱스를 구하는 배열 초기화
35+
val indices = IntArray(givenSize)
36+
for (i in 0 until givenSize) {
37+
indices[i] = i
38+
}
39+
40+
while (indices[givenSize - 1] < maxNumber) {
41+
processResult.add(indices.map { nums[it] }.sorted())
42+
var i = givenSize - 1
43+
44+
while (i >= 0 && indices[i] == i + maxNumber - givenSize) {
45+
i--
46+
}
47+
48+
if (i >= 0) {
49+
indices[i]++
50+
for (j in i + 1 until givenSize) {
51+
indices[j] = indices[j-1] + 1
52+
}
53+
} else break
54+
}
55+
56+
return processResult.filter { it.sum() == 0 }
57+
}
58+
59+
/**
60+
* case02. 투 포인터를 사용한 풀이
61+
* 조합을 사용한 풀이와 달리 시간 초과가 발생하지 않음. O(n^3)의 시간 복잡도를 O(n^2)으로 줄임
62+
*
63+
* 시간 복잡도:
64+
* -> 주어진 숫자 배열 오름차순으로 정렬: O(nlogn)
65+
* -> 세 개의 숫자를 더하는 로직
66+
* -> 외부 반복문을 통해 주어진 배열 전체 조회: O(n)
67+
* -> 내부 반복문을 통해 start to last index 순회: O(n)
68+
* -> O(n^2)
69+
* ∴ O(nlogn) + O(n^2) => O(n^2)
70+
*
71+
* 공간 복잡도:
72+
* -> 주어진 숫자 배열의 정렬을 담는 공간 필요: O(n)
73+
*/
74+
fun threeSum(nums: IntArray): List<List<Int>> {
75+
val processResult = mutableListOf<List<Int>>()
76+
val sortedNums = nums.sorted()
77+
78+
for (i in sortedNums.indices) {
79+
if (i > 0 && sortedNums[i] == sortedNums[i-1]) continue
80+
81+
var startIndex = i + 1
82+
var lastIndex = sortedNums.size - 1
83+
84+
while (startIndex < lastIndex) {
85+
val sum = sortedNums[i] + sortedNums[startIndex] + sortedNums[lastIndex]
86+
when {
87+
sum == 0 -> {
88+
processResult.add(listOf(sortedNums[i], sortedNums[startIndex], sortedNums[lastIndex]))
89+
while (startIndex < lastIndex && sortedNums[startIndex] == sortedNums[startIndex + 1]) startIndex++
90+
while (startIndex < lastIndex && sortedNums[lastIndex] == sortedNums[lastIndex - 1]) lastIndex--
91+
startIndex++
92+
lastIndex--
93+
}
94+
sum < 0 -> {
95+
startIndex++
96+
}
97+
else -> {
98+
lastIndex--
99+
}
100+
}
101+
}
102+
}
103+
return processResult
104+
}

3sum/GangBean.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
class Solution {
2+
public List<List<Integer>> threeSum(int[] nums) {
3+
/**
4+
1. understanding
5+
- integer array nums, find the whole combination of 3 nums, and the sum of the 3 nums equal to 0. And don't allow reusing same indiced number(but can duplicate in value)
6+
2. solve strategy
7+
- brute force
8+
- in every combination, validate sum of the nums equal to 0
9+
- but it can take O(N^3) times where N is the length of input array, and given that the N can be 3000 at most(3 * 10^3), time can be 27 * 10^9, which takes too long...
10+
- sort and two pointers
11+
- sort nums in ascending order, so move the left pointer to right means the sum of window is getting bigger.
12+
- and mid pointer set to left + 1 index
13+
- if sum of pointers is less than 0, then move mid pointer to right, until the sum is bigger than 0, and while processing them, if the sum of pointers is 0, then add the combination to the return list.
14+
- [-4, -1, -1, 0, 1, 2]:
15+
16+
3. complexity
17+
- time: O(N^2) -> each left pointer, you can search at most N-1, and left pointer's range is [0, N-1), so the max length is N-1 for left index pointer.
18+
- space: O(1) -> no extra space is needed
19+
*/
20+
// 0. assign return variable Set
21+
Set<List<Integer>> answer = new HashSet<>();
22+
23+
// 1. sort the num array in ascending order
24+
Arrays.sort(nums); // O(NlogN)
25+
// Arrays.stream(nums).forEach(System.out::println);
26+
27+
// 3. move the mid pointer from left to right to find the combination of which's sum is 0, and if the sum is over 0, and then move right pointer to the left. else if the sum is under 0, then move left pointer to right direction.
28+
for (int left = 0; left < nums.length - 1; left++) {
29+
int mid = left + 1;
30+
int right = nums.length - 1;
31+
while (mid < right) {
32+
// System.out.println(String.format("%d,%d,%d", nums[left], nums[mid], nums[right]));
33+
int sum = nums[left] + nums[mid] + nums[right];
34+
if (sum > 0) {
35+
right--;
36+
} else if (sum == 0) {
37+
answer.add(List.of(nums[left], nums[mid], nums[right]));
38+
right--;
39+
} else {
40+
mid++;
41+
}
42+
}
43+
}
44+
45+
return new ArrayList<>(answer);
46+
}
47+
}
48+

0 commit comments

Comments
 (0)