Skip to content

Commit a954889

Browse files
authored
Merge branch 'DaleStudy:main' into main
2 parents 3322146 + b504ef4 commit a954889

File tree

109 files changed

+2809
-5
lines changed

Some content is hidden

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

109 files changed

+2809
-5
lines changed

.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.event.pull_request.head.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 }}

contains-duplicate/HerrineKim.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// 시간복잡도: O(n)
2+
3+
/**
4+
* @param {number[]} nums
5+
* @return {boolean}
6+
*/
7+
var containsDuplicate = function (nums) {
8+
const seen = new Set();
9+
for (let num of nums) {
10+
if (seen.has(num)) {
11+
return true; // 중복 발견
12+
}
13+
seen.add(num);
14+
}
15+
return false; // 모든 요소가 고유
16+
};
17+

contains-duplicate/HodaeSsi.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from typing import List
2+
3+
class Solution:
4+
def containsDuplicate(self, nums: List[int]) -> bool:
5+
dict = {}
6+
for num in nums:
7+
dict[num] = dict.get(num, 0) + 1
8+
if dict[num] > 1:
9+
return True
10+
return False
11+

contains-duplicate/Jay-Mo-99.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class Solution(object):
2+
def containsDuplicate(self, nums):
3+
"""
4+
:type nums: List[int]
5+
:rtype: bool
6+
"""
7+
#해석
8+
#sets는 복수 요소를 허용하지 않는다(sets don't allow duplicate elements.)
9+
#만약 set에 기반된 list가 기존 nums와 길이가 다르다면 duplicate element가 있었다는 뜻이다.
10+
#If the length of the set created from nums is different from the original list(nums), It means there are duplicates.
11+
12+
#Big O
13+
#N: 주어진 배열 nums의 길이(Length of the input list nums)
14+
15+
#Time Complexity: O(N)
16+
#- set은 nums의 길이 n에 기반하여 생성된다(Creating a set from nums): O(N)
17+
#- 생성된 list와 기존 nums와의 비교는 상수(Comparing the lengths between created list and original list) : O(1)
18+
19+
#Space Complexity: O(N)
20+
#-set은 nums의 길이에 의해 생성되므로 n에 영향받음(The set requires extra space depends on the size of nums) : O(N)
21+
return len(list(set(nums))) != len(nums) #set된 list와 기존 nums의 len이 일치하지 않는다면 true(duplicate), 아니면 false
22+
23+

contains-duplicate/Jeehay28.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* @param {number[]} nums
3+
* @return {boolean}
4+
*/
5+
var containsDuplicate = function (nums) {
6+
return nums.length !== new Set(nums).size;
7+
};

contains-duplicate/KwonNayeon.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"""
2+
Title: 217. Contains Duplicate
3+
Link: https://leetcode.com/problems/contains-duplicate/
4+
5+
Summary:
6+
- 주어진 배열 `nums`에서 어떤 값이 한 번 이상 등장하면 True를 반환하고, 배열의 모든 값이 유일한 경우에는 False를 반환함
7+
- Input: `nums = [1,2,3,1]`
8+
- Output: `True`
9+
10+
Conditions:
11+
- 중복이 있으면: 배열에서 적어도 하나의 값이 두 번 이상 등장하면 `True` 반환
12+
- 중복이 없으면: 배열의 모든 값이 유일하면 `False` 반환
13+
"""
14+
15+
"""
16+
First Try
17+
Time Complexity:
18+
- O(n) * O(n) = O(n^2): `for` 루프에서 `nums.count(i)`를 호출할 때마다 리스트를 순회하므로, 전체 시간 복잡도는 `O(n^2)`
19+
"""
20+
class Solution:
21+
def containsDuplicate(self, nums: List[int]) -> bool:
22+
for i in nums:
23+
if nums.count(i) > 1:
24+
return True
25+
return False
26+
27+
"""
28+
Second Try (set를 활용하여 이미 본 요소를 효율적으로 추적하는 방법)
29+
Time Complexity:
30+
- O(n): `for` 루프에서 각 숫자에 대해 `in` 연산과 `add` 연산이 상수 시간 O(1)으로 처리되므로, 전체 시간 복잡도는 O(n)
31+
"""
32+
class Solution:
33+
def containsDuplicate(self, nums: List[int]) -> bool:
34+
seen = set()
35+
for i in nums:
36+
if i in seen:
37+
return True
38+
seen.add(i)
39+
return False

contains-duplicate/Real-Reason.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package leetcode_study
2+
3+
class SolutionContainsDuplicate {
4+
fun containsDuplicate(nums: IntArray): Boolean {
5+
val size = nums.size
6+
val numsToSet = nums.toSet()
7+
8+
return size != numsToSet.size
9+
}
10+
}

contains-duplicate/YeomChaeeun.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
function containsDuplicate(nums: number[]): boolean {
2+
3+
// 접근 (1) - 시간 복잡도가 매우 커서 실패
4+
// const uniqueArr = nums.filter((item, index) => { return nums.indexOf(item) === index })
5+
// console.log(uniqueArr)
6+
//
7+
// return nums.length !== uniqueArr.length;
8+
9+
// 접근 (2) - 양 옆의 값을 비교 =============
10+
// if(nums.length === 1)
11+
// return false;
12+
//
13+
// // 정렬
14+
// nums.sort()
15+
//
16+
// // 양 옆의 값을 비교
17+
// for(let i = 0; i < nums.length; i++){
18+
// console.log(nums[i], nums[i+1])
19+
// if(nums[i] === nums[i+1]){
20+
// return true;
21+
// }
22+
// }
23+
// return false;
24+
25+
// 접근 (3) - obj를 이용 ================
26+
let obj={}
27+
28+
for(let i = 0; i < nums.length; i++) {
29+
if(obj[nums[i]]) {
30+
return true;
31+
}
32+
obj[nums[i]] = 1;
33+
}
34+
return false;
35+
36+
};

contains-duplicate/aa601.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#include <stdio.h>
2+
#include <stdbool.h>
3+
4+
void merge(int *nums, int left, int mid, int right)
5+
{
6+
int i;
7+
int j;
8+
int k;
9+
int leftArr[mid - left + 1];
10+
int rightArr[right - mid];
11+
12+
i = -1;
13+
while (++i < mid - left + 1) // 왼쪽 분할된 부분 넣기
14+
leftArr[i] = nums[left + i];
15+
i = -1;
16+
while (++i < right - mid) // 오른쪽 분할된 부분 넣기
17+
rightArr[i] = nums[mid + i + 1];
18+
i = 0;
19+
j = 0;
20+
k = left; // **** nums배열인덱스 => left부터 시작
21+
// 나누어진 배열끼리 비교해서 nums배열 재배치
22+
while ((i < mid - left + 1) && (j < right - mid)) {
23+
if (leftArr[i] <= rightArr[j])
24+
nums[k] = leftArr[i++];
25+
else
26+
nums[k] = rightArr[j++];
27+
++k;
28+
}
29+
while (i < mid - left + 1) // left배열 남아있으면 마저 삽입
30+
nums[k++] = leftArr[i++];
31+
while (j < right - mid) // right배열 남아있으면 마저 삽입
32+
nums[k++] = rightArr[j++];
33+
}
34+
35+
void mergeSort(int *nums, int left, int right) {
36+
int mid;
37+
38+
if (left < right)
39+
{
40+
mid = (left + right) / 2;
41+
mergeSort(nums, left, mid); // 왼쪽분할
42+
mergeSort(nums, mid + 1, right); // 오른쪽분할
43+
merge(nums, left, mid, right);
44+
}
45+
}
46+
47+
bool containsDuplicate(int* nums, int numsSize) {
48+
int i;
49+
50+
mergeSort(nums, 0, numsSize - 1);
51+
i = -1;
52+
while (++i + 1 < numsSize) {
53+
if (nums[i] == nums[i + 1])
54+
return (true);
55+
}
56+
return (false);
57+
}
58+
59+
60+

contains-duplicate/anniemon.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* 시간 복잡도:
3+
* 맵에서 nums[i]를 찾거나 삽입하는 데 걸리는 시간 O(1) * n(nums.length)
4+
* 즉, O(n)
5+
* 공간 복잡도:
6+
* 최대 map의 크기는 nums.length만큼
7+
* 즉, O(n)
8+
*/
9+
/**
10+
* @param {number[]} nums
11+
* @return {boolean}
12+
*/
13+
var containsDuplicate = function(nums) {
14+
const map = new Map();
15+
for(let i = 0; i < nums.length; i++) {
16+
if(!map.has(nums[i])) {
17+
map.set(nums[i], i);
18+
} else {
19+
return true;
20+
}
21+
}
22+
return false;
23+
};

0 commit comments

Comments
 (0)