Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 226e7b3

Browse files
authoredDec 10, 2024
Merge branch 'DaleStudy:main' into main
2 parents 04e2345 + 4c3f57c commit 226e7b3

31 files changed

+915
-5
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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ jobs:
8585
- name: Check filename rules
8686
if: ${{ steps.pr-labels.outputs.has_maintenance != 'true' }}
8787
run: |
88-
files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | tr -d '"')
88+
files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} | tr -d '"')
8989
pr_author="${{ github.event.pull_request.user.login }}"
9090
success=true
9191

‎contains-duplicate/5YoonCheol.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Solution {
2+
/**
3+
* 시간 복잡도: O(N)
4+
* 공간 복잡도: O(N)
5+
*/
6+
public boolean containsDuplicate(int[] nums) {
7+
Set<Integer> set = new HashSet<>();
8+
9+
for (int num : nums) {
10+
if (set.contains(num)) return true;
11+
set.add(num);
12+
}
13+
14+
return false;
15+
}
16+
}

‎contains-duplicate/Gotprgmer.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import java.util.HashSet;
2+
import java.util.Set;
3+
4+
class SolutionGotprgmer {
5+
// 해당 문제는 어느 한 숫자가 2개이상 존재할 경우 true를 그렇지 않을 경우, false를 반환하는 문제이다.
6+
// set을 사용해서 set에 이미 값이 존재한다면 개수가 2 이상이므로 true 그렇지 않으면 false를 출력한다.
7+
8+
// 각 숫자들을 저장해서 set으로 관리 -> distinctNums
9+
// nums의 각 숫자인 checkNum을 distinctNums에 넣어준다.
10+
// 만약 checkNum이 이미 distinctNums에 존재한다면 ans를 true로 만들어주고 답을 출력한다.
11+
12+
13+
// 시간복잡도 -> O(n)
14+
// 공간복잡도 -> O(n)
15+
static Set<Integer> distinctNums;
16+
public boolean containsDuplicate(int[] nums) {
17+
distinctNums = new HashSet<>();
18+
boolean ans = false;
19+
for (int checkNum : nums) {
20+
if (distinctNums.contains(checkNum)) {
21+
ans = true;
22+
break;
23+
};
24+
distinctNums.add(checkNum);
25+
}
26+
return ans;
27+
}
28+
29+
30+
}

‎contains-duplicate/JisooPyo.kt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package leetcode_study
2+
3+
import io.kotest.matchers.shouldBe
4+
import org.junit.jupiter.api.Test
5+
6+
/**
7+
* Leetcode
8+
* 217. Contains Duplicate
9+
* Easy
10+
*/
11+
class ContainsDuplicate {
12+
/**
13+
* Runtime: 17 ms(Beats: 80.99 %)
14+
* Time Complexity: O(n)
15+
* - 배열 순회
16+
*
17+
* Memory: 50.63 MB(Beats: 70.32 %)
18+
* Space Complexity: O(n)
19+
* - HashSet에 최악의 경우 배열 원소 모두 저장
20+
*/
21+
fun containsDuplicate(nums: IntArray): Boolean {
22+
val set = hashSetOf<Int>()
23+
for (i in nums) {
24+
if (set.contains(i)) {
25+
return true
26+
}
27+
set.add(i)
28+
}
29+
return false
30+
}
31+
32+
@Test
33+
fun test() {
34+
containsDuplicate(intArrayOf(1, 2, 3, 1)) shouldBe true
35+
containsDuplicate(intArrayOf(1, 2, 3, 4)) shouldBe false
36+
containsDuplicate(intArrayOf(1, 1, 1, 3, 3, 4, 3, 2, 4, 2)) shouldBe true
37+
}
38+
}

‎contains-duplicate/dusunax.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'''
2+
# Leetcode 217. Contains Duplicate
3+
4+
use set to store distinct elements 🗂️
5+
6+
## Time and Space Complexity
7+
8+
```
9+
TC: O(n)
10+
SC: O(n)
11+
```
12+
13+
### TC is O(n):
14+
- iterating through the list just once to convert it to a set.
15+
16+
### SC is O(n):
17+
- creating a set to store the distinct elements of the list.
18+
'''
19+
20+
class Solution:
21+
def containsDuplicate(self, nums: List[int]) -> bool:
22+
return len(nums) != len(set(nums))
23+

‎contains-duplicate/jeldo.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class Solution:
2+
# O(n)
3+
def containsDuplicate(self, nums: list[int]) -> bool:
4+
return len(nums) != len(set(nums)) # O(n)

‎contains-duplicate/thispath98.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
"""
2+
# Time Complexity: O(N)
3+
- N번 순회
4+
# Space Compelexity: O(N)
5+
- 최악의 경우 (중복된 값이 없을 경우) N개 저장
6+
"""
7+
class Solution:
8+
def containsDuplicate(self, nums: List[int]) -> bool:
9+
num_dict = {}
10+
for num in nums:
11+
if num not in num_dict:
12+
num_dict[num] = True
13+
else:
14+
return True
15+
return False

‎house-robber/5YoonCheol.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class Solution {
2+
public int rob(int[] nums) {
3+
//배열 길이 0이면 털 수 있는 집이 없음.
4+
if (nums.length == 0) return 0;
5+
//배열 길이가 1이면 한 집만 털 수 있음.
6+
if (nums.length == 1) return nums[0];
7+
8+
//동적 계획법으로 풀이
9+
int[] dp = new int[nums.length];
10+
dp[0] = nums[0];
11+
dp[1] = Math.max(nums[0], nums[1]);
12+
13+
//배열 크기가 2이상일 경우 최대 금액의 범위 확장
14+
for (int i = 2; i < nums.length; i++) {
15+
dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);
16+
}
17+
return dp[nums.length - 1];
18+
}
19+
}

‎house-robber/JisooPyo.kt

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package leetcode_study
2+
3+
import io.kotest.matchers.shouldBe
4+
import org.junit.jupiter.api.Test
5+
import kotlin.math.max
6+
7+
/**
8+
* Leetcode
9+
* 198. House Robber
10+
* Medium
11+
*
12+
* 사용된 알고리즘: Dynamic Programming
13+
*
14+
* i번째 집에서 얻을 수 있는 최대 금액은 다음 두 가지 중 큰 값입니다.
15+
* - (i-2)번째 집까지의 최대 금액 + 현재 집의 금액
16+
* - (i-1)번째 집까지의 최대 금액
17+
*/
18+
class HouseRobber {
19+
/**
20+
* Runtime: 0 ms(Beats: 100.00 %)
21+
* Time Complexity: O(n)
22+
*
23+
* Memory: 34.65 MB(Beats: 40.50 %)
24+
* Space Complexity: O(n)
25+
*/
26+
fun rob(nums: IntArray): Int {
27+
if (nums.size == 1) {
28+
return nums[0]
29+
}
30+
if (nums.size == 2) {
31+
return max(nums[0], nums[1])
32+
}
33+
val dp = IntArray(nums.size)
34+
dp[0] = nums[0]
35+
dp[1] = max(nums[0], nums[1])
36+
for (i in 2 until nums.size) {
37+
dp[i] = max(dp[i - 2] + nums[i], dp[i - 1])
38+
}
39+
return dp[nums.size - 1]
40+
}
41+
42+
/**
43+
* 공간 복잡도를 개선
44+
* Runtime: 0 ms(Beats: 100.00 %)
45+
* Time Complexity: O(n)
46+
*
47+
* Memory: 34.95 MB(Beats: 36.98 %)
48+
* Space Complexity: O(1)
49+
*/
50+
fun rob2(nums: IntArray): Int {
51+
if (nums.size == 1) return nums[0]
52+
if (nums.size == 2) return max(nums[0], nums[1])
53+
54+
var twoBack = nums[0]
55+
var oneBack = max(nums[0], nums[1])
56+
var current = oneBack
57+
58+
for (i in 2 until nums.size) {
59+
current = max(twoBack + nums[i], oneBack)
60+
twoBack = oneBack
61+
oneBack = current
62+
}
63+
64+
return current
65+
}
66+
67+
@Test
68+
fun test() {
69+
rob(intArrayOf(1, 2, 3, 1)) shouldBe 4
70+
rob(intArrayOf(2, 7, 9, 3, 1)) shouldBe 12
71+
rob2(intArrayOf(1, 2, 3, 1)) shouldBe 4
72+
rob2(intArrayOf(2, 7, 9, 3, 1)) shouldBe 12
73+
}
74+
}

‎house-robber/dusunax.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
'''
2+
# Leetcode 198. House Robber
3+
4+
use **dynamic programming** to solve this problem. (bottom-up approach) 🧩
5+
6+
choose bottom-up approach for less space complexity.
7+
8+
## DP relation
9+
10+
```
11+
dp[i] = max(dp[i - 1], dp[i - 2] + nums[i])
12+
```
13+
14+
- **dp[i - 1]:** skip and take the value from the previous house
15+
- **dp[i - 2]:** rob the current house, add its value to the maximum money from two houses before
16+
17+
## Time and Space Complexity
18+
19+
```
20+
TC: O(n)
21+
SC: O(n)
22+
```
23+
24+
### TC is O(n):
25+
- iterating through the list just once to calculate the maximum money. = O(n)
26+
27+
### SC is O(n):
28+
- using a list to store the maximum money at each house. = O(n)
29+
30+
'''
31+
32+
class Solution:
33+
def rob(self, nums: List[int]) -> int:
34+
if len(nums) == 1:
35+
return nums[0]
36+
37+
dp = [0] * len(nums)
38+
dp[0] = nums[0]
39+
dp[1] = max(nums[0], nums[1])
40+
41+
for i in range(2, len(nums)):
42+
dp[i] = max(dp[i - 1], dp[i - 2] + nums[i])
43+
44+
return dp[-1]

‎house-robber/jeldo.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class Solution:
2+
# O(n)
3+
def rob(self, nums: list[int]) -> int:
4+
if len(nums) <= 2:
5+
return max(nums)
6+
nums[2] += nums[0]
7+
for i in range(3, len(nums)):
8+
nums[i] += max(nums[i-3], nums[i-2])
9+
return max(nums[-1], nums[-2])

‎house-robber/thispath98.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"""
2+
# Time Complexity: O(N)
3+
- N개의 개수를 가지는 dp 리스트를 만들고, 이를 순회
4+
# Space Compelexity: O(N)
5+
- N개의 dp 리스트 저장
6+
"""
7+
class Solution:
8+
def rob(self, nums: List[int]) -> int:
9+
if len(nums) == 1:
10+
return nums[0]
11+
12+
dp = [0 for _ in range(len(nums))]
13+
dp[0] = nums[0]
14+
dp[1] = max(nums[0], nums[1])
15+
16+
for i in range(len(nums) - 2):
17+
dp[i + 2] = max(dp[i] + nums[i + 2], dp[i + 1])
18+
19+
return max(dp[-2], dp[-1])
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""
2+
# Time Complexity: O(N)
3+
- lce_dict 생성: N
4+
- N개의 key에 대하여 순회하면서 값 확인: N
5+
# Space Compelexity: O(k)
6+
- 중복되지 않은 key k개 저장
7+
"""
8+
class Solution:
9+
def longestConsecutive(self, nums: List[int]) -> int:
10+
if not nums:
11+
return 0
12+
13+
lce_dict = {}
14+
for num in nums:
15+
lce_dict[num] = True
16+
17+
answer = 0
18+
for num in nums:
19+
cur_lce = 1
20+
if lce_dict.pop(num, None) is None:
21+
continue
22+
23+
down_num = num - 1
24+
while down_num in lce_dict:
25+
cur_lce += 1
26+
lce_dict.pop(down_num)
27+
down_num -= 1
28+
29+
up_num = num + 1
30+
while up_num in lce_dict:
31+
cur_lce += 1
32+
lce_dict.pop(up_num)
33+
up_num += 1
34+
35+
answer = answer if answer > cur_lce else cur_lce
36+
37+
return answer
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import java.util.*;
2+
3+
class Solution {
4+
public int longestConsecutive(int[] nums) {
5+
if (nums == null || nums.length == 0) return 0;
6+
7+
//모든 요소 HashSet 삽입
8+
HashSet<Integer> set = new HashSet<>();
9+
for (int num : nums) {
10+
set.add(num);
11+
}
12+
13+
int longest = 0;
14+
15+
// 시작지점 체크
16+
for (int num : nums) {
17+
//배열 요소보다 1 작은 수 가 없는 경우 새로운 시작 지점이 됨
18+
if (!set.contains(num - 1)) {
19+
int start = num;
20+
int currentLength = 1;
21+
22+
// 1씩 증가시키면서 연속된 수의 개수 탐색
23+
while (set.contains(start + 1)) {
24+
start++;
25+
currentLength++;
26+
}
27+
// 기존 longest와 현재 연속된 수를 비교
28+
longest = Math.max(longest, currentLength);
29+
}
30+
}
31+
32+
return longest;
33+
}
34+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package leetcode_study
2+
3+
import io.kotest.matchers.shouldBe
4+
import org.junit.jupiter.api.Test
5+
import kotlin.math.max
6+
7+
/**
8+
* Leetcode
9+
* 128. Longest Consecutive Sequence
10+
* Medium
11+
*/
12+
class LongestConsecutiveSequence {
13+
/**
14+
* Runtime: 58 ms(Beats: 79.06 %)
15+
* Time Complexity: O(n)
16+
* - while 루프의 총 반복 횟수는 n을 넘을 수 없다.
17+
*
18+
* Memory: 62.65 MB(Beats: 10.48 %)
19+
* Space Complexity: O(n)
20+
*/
21+
fun longestConsecutive(nums: IntArray): Int {
22+
val numsSet: MutableSet<Int> = nums.toHashSet()
23+
val startSet: MutableSet<Int> = hashSetOf()
24+
25+
// 수열의 시작점이 될 수 있는 수를 찾는다.
26+
for (num in numsSet) {
27+
if (!numsSet.contains(num - 1)) {
28+
startSet.add(num)
29+
}
30+
}
31+
var answer = 0
32+
for (start in startSet) {
33+
// 수열의 시작점부터 몇 개 까지 numsSet에 있는지 확인한다.
34+
var count = 0
35+
var first = start
36+
while (numsSet.contains(first)) {
37+
first++
38+
count++
39+
}
40+
// 최대 수열의 개수를 업데이트한다.
41+
answer = max(answer, count)
42+
}
43+
return answer
44+
}
45+
46+
/**
47+
* 위 풀이에서 startSet을 제거하여 공간적으로 효율적인 풀이
48+
* Runtime: 63 ms(Beats: 65.70 %)
49+
* Time Complexity: O(n)
50+
*
51+
* Memory: 58.47 MB(Beats: 70.81 %)
52+
* Space Complexity: O(n)
53+
*/
54+
fun longestConsecutive2(nums: IntArray): Int {
55+
val numsSet = nums.toHashSet()
56+
var maxLength = 0
57+
58+
for (num in numsSet) {
59+
if (!numsSet.contains(num - 1)) {
60+
var currentNum = num
61+
var currentLength = 0
62+
63+
while (numsSet.contains(currentNum)) {
64+
currentLength++
65+
currentNum++
66+
}
67+
maxLength = max(maxLength, currentLength)
68+
}
69+
}
70+
return maxLength
71+
}
72+
73+
@Test
74+
fun test() {
75+
longestConsecutive(intArrayOf(100, 4, 200, 1, 3, 2)) shouldBe 4
76+
longestConsecutive(intArrayOf(0, 3, 7, 2, 5, 8, 4, 6, 0, 1)) shouldBe 9
77+
78+
longestConsecutive2(intArrayOf(100, 4, 200, 1, 3, 2)) shouldBe 4
79+
longestConsecutive2(intArrayOf(0, 3, 7, 2, 5, 8, 4, 6, 0, 1)) shouldBe 9
80+
}
81+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
'''
2+
# Leetcode 128. Longest Consecutive Sequence
3+
4+
keep time complexity O(n) by iterating through the set and accessing elements in O(1) time. ⚖️
5+
6+
## Time and Space Complexity
7+
```
8+
TC: O(n)
9+
SC: O(n)
10+
```
11+
12+
### TC is O(n):
13+
- iterating through the set. O(n)
14+
- accessing elements in the set. O(1)
15+
- while loop incrementing `current_num` while `current_num + 1 in nums_set`. O(1)
16+
17+
### SC is O(n):
18+
- creating a set from the list of numbers. O(n)
19+
'''
20+
21+
class Solution:
22+
def longestConsecutive(self, nums: List[int]) -> int:
23+
nums_set = set(nums) # O(n)
24+
longest_sequence = 0
25+
26+
for num in nums_set: # O(n)
27+
if (num - 1) not in nums_set:
28+
current_num = num
29+
current_sequence = 1
30+
31+
while current_num + 1 in nums_set: # O(1)
32+
current_num += 1
33+
current_sequence += 1
34+
35+
longest_sequence = max(current_sequence, longest_sequence)
36+
37+
return longest_sequence
38+

‎longest-consecutive-sequence/jeldo.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class Solution:
2+
# O(n)
3+
def longestConsecutive(self, nums: list[int]) -> int:
4+
max_length = 0
5+
nums_set = set(nums)
6+
for n in nums_set:
7+
if n - 1 not in nums_set:
8+
length = 0
9+
while n + length in nums_set:
10+
length += 1
11+
max_length = max(max_length, length)
12+
13+
return max_length
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import java.util.*;
2+
3+
class Solution {
4+
public int[] topKFrequent(int[] nums, int k) {
5+
Map<Integer, Integer> map = new HashMap<>();
6+
for (int num : nums) {
7+
map.put(num, map.getOrDefault(num, 0) + 1);
8+
}
9+
10+
//value값을 통한 key 정렬
11+
List<Integer> list = new ArrayList<>(map.keySet());
12+
list.sort((a,b)->map.get(b) - map.get(a));
13+
14+
//상위 k개 key 추출
15+
int[] res = new int[k];
16+
for (int i = 0; i < k; i++) {
17+
res[i] = list.get(i);
18+
}
19+
return res;
20+
}
21+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// 각 수의 개수를 카운트 하고 카운트 한 값을 기준으로 정렬하여 우선순위 큐로
2+
// k개를 추출하여 result 리스트에 담는다.
3+
4+
// 시간복잡도 : O(NlogN)
5+
// 공간복잡도 : O(N)
6+
7+
8+
public class SolutionGotprgmer {
9+
10+
public int[] topKFrequent(int[] nums, int k) {
11+
Map<Integer, Integer> map = new HashMap<>();
12+
for(int num:nums){
13+
map.put(num,map.getOrDefault(num,0)+1);
14+
}
15+
PriorityQueue<Map.Entry<Integer, Integer>> pq = new PriorityQueue<>(
16+
(e1, e2) -> e2.getValue().compareTo(e1.getValue())
17+
);
18+
for (Map.Entry<Integer,Integer> entry : map.entrySet()){
19+
pq.offer(entry);
20+
}
21+
22+
int[] result = new int[k];
23+
for(int ansIdx=0;ansIdx < k; ansIdx++){
24+
result[ansIdx] = pq.poll().getKey();
25+
}
26+
return result;
27+
}
28+
}

‎top-k-frequent-elements/JisooPyo.kt

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package leetcode_study
2+
3+
import io.kotest.matchers.shouldBe
4+
import org.junit.jupiter.api.Test
5+
import java.util.*
6+
7+
/**
8+
* Leetcode
9+
* 347. Top K Frequent Elements
10+
* Medium
11+
*/
12+
class TopKFrequentElements {
13+
/**
14+
* Runtime: 30 ms(Beats: 68.62 %)
15+
* Time Complexity: O(n log n)
16+
* - list 정렬
17+
*
18+
* Memory: 42.20 MB(Beats: 58.82 %)
19+
* Space Complexity: O(n)
20+
*/
21+
fun topKFrequent(nums: IntArray, k: Int): IntArray {
22+
val countMap: MutableMap<Int, Int> = HashMap()
23+
24+
for (num in nums) {
25+
countMap[num] = countMap.getOrDefault(num, 0) + 1
26+
}
27+
28+
val list = mutableListOf<Node>()
29+
for (key in countMap.keys) {
30+
list.add(Node(key, countMap[key]!!))
31+
}
32+
list.sortDescending()
33+
34+
val answer = IntArray(k)
35+
for (i in 0 until k) {
36+
answer[i] = list[i].value
37+
}
38+
return answer
39+
}
40+
41+
/**
42+
* 개선된 버전: 우선순위 큐를 사용
43+
*
44+
* Runtime: 19 ms(Beats: 96.30 %)
45+
* Time Complexity: O(n log n)
46+
*
47+
* Memory: 44.83 MB(Beats: 18.35 %)
48+
* Space Complexity: O(n)
49+
*/
50+
fun topKFrequent2(nums: IntArray, k: Int): IntArray {
51+
val countMap = nums.groupBy { it }
52+
.mapValues { it.value.size }
53+
54+
val pq = PriorityQueue<Node>(compareByDescending { it.count })
55+
countMap.forEach { (num, count) ->
56+
pq.offer(Node(num, count))
57+
}
58+
59+
return IntArray(k) { pq.poll().value }
60+
}
61+
62+
data class Node(var value: Int, var count: Int) : Comparable<Node> {
63+
override fun compareTo(other: Node): Int {
64+
return this.count.compareTo(other.count)
65+
}
66+
}
67+
68+
@Test
69+
fun test() {
70+
topKFrequent(intArrayOf(1, 1, 1, 2, 2, 3), 2) shouldBe intArrayOf(1, 2)
71+
topKFrequent(intArrayOf(1), 1) shouldBe intArrayOf(1)
72+
73+
topKFrequent2(intArrayOf(1, 1, 1, 2, 2, 3), 2) shouldBe intArrayOf(1, 2)
74+
topKFrequent2(intArrayOf(1), 1) shouldBe intArrayOf(1)
75+
}
76+
}

‎top-k-frequent-elements/dusunax.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
'''
2+
# Leetcode 347. Top K Frequent Elements
3+
4+
use **Counter** to count the frequency of each element in the list 🚀
5+
6+
- **solution 1**: use **sorted()** to sort the elements by their frequency in descending order.
7+
- **solution 2**: use **bucket sort** to sort the elements by their frequency in descending order. (efficient!)
8+
9+
## Time and Space Complexity
10+
11+
### solution 1: topKFrequent()
12+
13+
```
14+
TC: O(n log n)
15+
SC: O(n)
16+
```
17+
18+
#### TC is O(n log n):
19+
- iterating through the list just once to count the frequency of each element. = O(n)
20+
- sorting the elements by their frequency in descending order. = O(n log n)
21+
22+
#### SC is O(n):
23+
- using a Counter to store the frequency of each element. = O(n)
24+
- sorted() creates a new list that holds the elements of frequency_map. = O(n)
25+
- result list that holds the top k frequent elements. = O(k)
26+
27+
### solution 2: topKFrequentBucketSort()
28+
29+
```
30+
TC: O(n)
31+
SC: O(n)
32+
```
33+
34+
#### TC is O(n):
35+
- iterating through the list just once to count the frequency of each element. = O(n)
36+
- creating **buckets** to store the elements by their frequency. = O(n)
37+
- iterating through the buckets in reverse order to get only the top k frequent elements. = O(n)
38+
39+
#### SC is O(n):
40+
- using a Counter to store the frequency of each element. = O(n)
41+
- using buckets to store the elements by their frequency. = O(n)
42+
- result list that holds only the top k frequent elements. = O(k)
43+
'''
44+
45+
class Solution:
46+
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
47+
frequency_map = Counter(nums) # TC: O(n), SC: O(n)
48+
sorted_frequencies = sorted(frequency_map.items(), key=lambda x: x[1], reverse=True) # TC: O(n log n), SC: O(n)
49+
50+
result = [] # SC: O(k)
51+
for e in sorted_frequencies: # TC: O(k)
52+
result.append(e[0])
53+
54+
return result[0:k]
55+
56+
def topKFrequentBucketSort(self, nums: List[int], k: int) -> List[int]:
57+
frequency_map = Counter(nums)
58+
n = len(nums)
59+
buckets = [[] for _ in range(n + 1)]
60+
61+
for num, freq in frequency_map.items():
62+
buckets[freq].append(num)
63+
64+
result = []
65+
for i in range(len(buckets) - 1, 0, -1):
66+
for num in buckets[i]:
67+
result.append(num)
68+
if len(result) == k:
69+
return result

‎top-k-frequent-elements/jeldo.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from collections import Counter
2+
import heapq
3+
4+
5+
class Solution:
6+
# O(nlogn)
7+
def topKFrequent(self, nums: list[int], k: int) -> list[int]:
8+
ls = [(key, value) for key, value in Counter(nums).items()] # O(n)
9+
return [key for _, key in heapq.nlargest(n=k, iterable=ls)] # O(nlogn)

‎top-k-frequent-elements/thispath98.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""
2+
# Time Complexity: O(N log N)
3+
- Counter 생성: N번 순회
4+
- most common 연산: N log N
5+
# Space Compelexity: O(N)
6+
- 최악의 경우 (중복된 값이 없을 경우) N개 저장
7+
"""
8+
from collections import Counter
9+
10+
11+
class Solution:
12+
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
13+
count_dict = Counter(nums)
14+
top_k_list = count_dict.most_common(k)
15+
answer = [key for key, value in top_k_list]
16+
return answer

‎valid-palindrome/5YoonCheol.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Solution {
2+
public boolean isPalindrome(String s) {
3+
//정규식으로 영문,숫자 아닌 경우 "" 치환
4+
//StringBuilder를 통해 문자열 가공
5+
//거꾸로 뒤집은 것과 원래의 문자열이 일치할 경우 팰린드롬
6+
s = s.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();
7+
StringBuilder sb = new StringBuilder(s);
8+
if(sb.reverse().toString().equals(s)){
9+
return true;
10+
}
11+
12+
return false;
13+
}
14+
}
15+
16+

‎valid-palindrome/Gotprgmer.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// 입력된 문자 중 알파벳이나 숫자가 아닌 값들을 하나의 문자열로 만든다.
2+
// 이때 모든 문자들을 소문자로 바꾼다.
3+
// 역정렬한 값과 원래 값을 비교해 팰린드롬 유무를 출력한다.
4+
5+
// 알파벳 혹은 숫자가 아닌지 검사하는 문자 -> charToCheck
6+
7+
// 시간복잡도 : O(n)
8+
// 공간복잡도 : O(n)
9+
10+
class Solution_Gotprgmer {
11+
public boolean validPalindrome(String s) {
12+
StringBuilder sb = new StringBuilder();
13+
for(char charToCheck : s.toCharArray()){
14+
if(!Character.isLetterOrDigit(charToCheck)){
15+
continue;
16+
}
17+
sb.append(Character.toLowerCase(charToCheck));
18+
}
19+
String originalDirection = sb.toString();
20+
String reDirection = sb.reverse().toString();
21+
22+
return originalDirection.equals(reDirection);
23+
}
24+
}

‎valid-palindrome/JisooPyo.kt

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package leetcode_study
2+
3+
import io.kotest.matchers.shouldBe
4+
import org.junit.jupiter.api.Test
5+
6+
/**
7+
* Leetcode
8+
* 125. Valid Palindrome
9+
* Easy
10+
*/
11+
class ValidPalindrome {
12+
/**
13+
* Runtime: 4 ms(Beats: 98.27 %)
14+
* Time Complexity: O(n)
15+
*
16+
* Memory: 38.22 MB(Beats: 46.74 %)
17+
* Space Complexity: O(1)
18+
*/
19+
fun isPalindrome(s: String): Boolean {
20+
var left = 0
21+
var right = s.length - 1
22+
while (left <= right) {
23+
when (s[left]) {
24+
// 왼쪽의 문자가 alphanumeric일 때
25+
in 'a'..'z', in 'A'..'Z', in '0'..'9' -> {
26+
27+
when (s[right]) {
28+
// 오른쪽의 문자가 alphanumeric일 때
29+
in 'a'..'z', in 'A'..'Z', in '0'..'9' -> {
30+
// 문자 비교
31+
if (s[left].equals(s[right], true)) {
32+
left++
33+
right--
34+
continue
35+
} else {
36+
return false
37+
}
38+
}
39+
// 오른쪽의 문자가 alphanumeric이 아닐 때
40+
else -> {
41+
right--
42+
continue
43+
}
44+
}
45+
}
46+
47+
// 왼쪽의 문자가 alphanumeric이 아닐 때
48+
else -> {
49+
left++
50+
continue
51+
}
52+
}
53+
}
54+
return true
55+
}
56+
57+
/**
58+
* 개선한 버전
59+
* Runtime: 5 ms(Beats: 87.14 %)
60+
* Time Complexity: O(n)
61+
*
62+
* Memory: 37.76 MB(Beats: 61.52 %)
63+
* Space Complexity: O(1)
64+
*/
65+
fun isPalindrome2(s: String): Boolean {
66+
var left = 0
67+
var right = s.length - 1
68+
69+
while (left < right) {
70+
// 왼쪽에서 유효한 문자를 찾음
71+
while (left < right && !s[left].isLetterOrDigit()) {
72+
left++
73+
}
74+
75+
// 오른쪽에서 유효한 문자를 찾음
76+
while (left < right && !s[right].isLetterOrDigit()) {
77+
right--
78+
}
79+
80+
// 문자 비교
81+
if (!s[left].equals(s[right], ignoreCase = true)) {
82+
return false
83+
}
84+
85+
left++
86+
right--
87+
}
88+
return true
89+
}
90+
91+
@Test
92+
fun test() {
93+
isPalindrome("A man, a plan, a canal: Panama") shouldBe true
94+
isPalindrome("race a car") shouldBe false
95+
isPalindrome(" ") shouldBe true
96+
97+
isPalindrome2("A man, a plan, a canal: Panama") shouldBe true
98+
isPalindrome2("race a car") shouldBe false
99+
isPalindrome2(" ") shouldBe true
100+
}
101+
}

‎valid-palindrome/dusunax.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'''
2+
# Leetcode 125. Valid Palindrome
3+
4+
use `isalnum()` to filter out non-alphanumeric characters 🔍
5+
6+
## Time and Space Complexity
7+
8+
```
9+
TC: O(n)
10+
SC: O(n)
11+
```
12+
13+
### TC is O(n):
14+
- iterating through the string just once to filter out non-alphanumeric characters. O(n)
15+
16+
### SC is O(n):
17+
- `s.lower()` creates a new string. O(n)
18+
- creating a new string `converted_s` to store the filtered characters. O(n)
19+
- `converted_s[::-1]` creates a new reversed string. O(n)
20+
'''
21+
22+
class Solution:
23+
def isPalindrome(self, s: str) -> bool:
24+
if s == " ":
25+
return True
26+
27+
s = s.lower()
28+
converted_s = ''.join(c for c in s if c.isalnum())
29+
30+
return converted_s == converted_s[::-1]
31+

‎valid-palindrome/jeldo.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class Solution:
2+
# O(n)
3+
def isPalindrome(self, s: str) -> bool:
4+
s = ''.join(ch.lower() for ch in s if ch.isalnum()) # O(n)
5+
return s == s[::-1] # O(n)

‎valid-palindrome/thispath98.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""
2+
# Time Complexity: O(N)
3+
- N개의 char를 각각 한번씩 순회
4+
# Space Compelexity: O(N)
5+
- 최악의 경우 (공백이 없을 경우) N개의 char 저장
6+
"""
7+
class Solution:
8+
def isPalindrome(self, s: str) -> bool:
9+
string = [char.lower() for char in s if char.isalnum()]
10+
for i in range(len(string) // 2):
11+
if string[i] != string[-i - 1]:
12+
return False
13+
return True

0 commit comments

Comments
 (0)
Please sign in to comment.