Skip to content

Commit 40afe41

Browse files
Merge branch 'DaleStudy:main' into main
2 parents 7aa7393 + 74f06db commit 40afe41

File tree

20 files changed

+1349
-0
lines changed

20 files changed

+1349
-0
lines changed

β€Ž3sum/haxr369.javaβ€Ž

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import java.util.ArrayList;
2+
import java.util.Arrays;
3+
import java.util.HashSet;
4+
import java.util.List;
5+
import java.util.Set;
6+
7+
/**
8+
* μ„Έ 수의 μΈλ±μŠ€κ°€ λͺ¨λ‘ λ‹€λ₯΄κ³  μ„Έ 수 합이 0인 경우의 수λ₯Ό κ΅¬ν•˜κΈ°
9+
* μ„Έ μˆ«μžκ°€ λ“€μ–΄κ°„ 배열은 μ€‘λ³΅λ˜κ²Œ ν•˜μ§€ μ•Šμ€λ‹€.
10+
*
11+
* 1. λͺ¨λ“  경우의 수λ₯Ό κ΅¬ν•œλ‹€. => O(N^3)
12+
* 3000*3000*3000 == 9*10^9 => 9얡건...
13+
* 2. left, mid, right라고 ν•  λ•Œ, midλ₯Ό κ³ μ •ν•˜κ³  left, right만 μ›€μ§μ΄λŠ” two pointerλ₯Ό μ‘μš©ν•˜κΈ°
14+
*/
15+
class Solution {
16+
/**
17+
* Runtime: 545 ms (Beats 14.44%)
18+
* Memory: 60.78 MB (Beats 5.38%)
19+
* Space Complexity: O(N)
20+
* - 정렬을 μœ„ν•œ 곡간 => O(N)
21+
* - μ„Έ 수λ₯Ό μ €μž₯ν•˜κΈ° μœ„ν•œ 리슀트 => O(3)
22+
* > O(N) + O(3) => O(N)
23+
* Time Complexity: O(NlogN)
24+
* - 정렬을 μœ„ν•œ μ‹œκ°„ => O(NlogN)
25+
* - mid의 순회 => O(N)
26+
* - two pointer 쑰회 => O(N)
27+
* > O(NlogN) + O(N)*O(N) ~= O(N^2)
28+
*/
29+
public List<List<Integer>> threeSum(int[] nums) {
30+
int L = nums.length;
31+
Arrays.sort(nums);
32+
33+
Set<List<Integer>> st = new HashSet<>();
34+
35+
// midλ₯Ό λŠ˜λ €κ°€λ©΄μ„œ 투 포인터 μ§„ν–‰
36+
for (int mid = 1; mid < L - 1; mid++) {
37+
int left = 0;
38+
int right = L - 1;
39+
while (left < mid && mid < right) {
40+
int sm = nums[left] + nums[mid] + nums[right];
41+
if (sm == 0) {
42+
/**
43+
* leftλ₯Ό λ”ν•˜λŠ” 이유:
44+
* ν˜„μž¬ 찾은 경우의 수 외에 λ‹€λ₯Έ κ²½μš°κ°€ μ‘΄μž¬ν•  수 있음
45+
* ex) -7,1,6 / -6,1,5
46+
* => midλŠ” κ³ μ •μ΄μ§€λ§Œ, leftλŠ” 늘리고 rightλ₯Ό μ€„μ—¬μ„œ 0을 λ§Œλ“€ 수 μžˆλŠ” λ‹€λ₯Έ κ²½μš°κ°€ 있음
47+
*/
48+
List<Integer> li = new ArrayList<>();
49+
li.add(nums[left]);
50+
li.add(nums[mid]);
51+
li.add(nums[right]);
52+
st.add(li); // 쀑볡값이 μžˆμ–΄λ„ λ¬΄μ‹œν•  수 있음.
53+
left++;
54+
} else if (sm < 0) { // λΆ€μ‘±ν•˜λ©΄ left 늘리기
55+
left++;
56+
} else { // κ³Όν•˜λ©΄ right 쀄이기
57+
right--;
58+
}
59+
}
60+
}
61+
62+
return new ArrayList<>(st);
63+
}
64+
}

β€Ž3sum/ppxyn1.pyβ€Ž

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# idea: sorting + two pointer
2+
# The idea was straightforward, but remove the duplication logic was the tricky.
3+
4+
class Solution:
5+
def threeSum(self, nums: List[int]) -> List[List[int]]:
6+
nums.sort()
7+
n = len(nums)
8+
answer = []
9+
10+
for i in range(n):
11+
if i > 0 and nums[i] == nums[i-1]:
12+
continue
13+
14+
left, right = i+1, n-1
15+
16+
while left < right:
17+
s = nums[i] + nums[left] + nums[right]
18+
if s == 0:
19+
answer.append([nums[i], nums[left], nums[right]])
20+
while left < right and nums[left] == nums[left+1]:
21+
left += 1
22+
while left < right and nums[right] == nums[right-1]:
23+
right -= 1
24+
left += 1
25+
right -= 1
26+
elif s < 0:
27+
left += 1
28+
else:
29+
right -= 1
30+
return answer
31+
32+

β€Ž3sum/samcho0608.javaβ€Ž

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import java.util.ArrayList;
2+
import java.util.Arrays;
3+
import java.util.List;
4+
5+
// link: https://leetcode.com/problems/3sum/
6+
// difficulty: Medium
7+
class Solution {
8+
// Problem:
9+
// * return: all triplets of elements in nums such that the sum == 0 (indices must differ)
10+
// Solution:
11+
// * Time Complexity: O(N^2)
12+
// * Space Complexity: O(1)
13+
public List<List<Integer>> threeSum(int[] nums) {
14+
// sort for simplicity
15+
// Time Complexity: O(N log N)
16+
Arrays.sort(nums);
17+
18+
List<List<Integer>> answers = new ArrayList<>();
19+
20+
// if there are only positive or only negative numbers, there exist no solution
21+
if(nums[0] > 0 || nums[nums.length-1] < 0) return answers;
22+
23+
24+
25+
// Time Complexity: O(N^2)
26+
// * for loop * inner while loop = O(N) * O(N) = O(N^2)
27+
28+
// nums[i]: first of the triplet
29+
// * skip positive because the other two will also be positive
30+
for(int i = 0; i < nums.length && nums[i] <= 0; i++) {
31+
// skip if same first of the triplet met
32+
if(i != 0 && nums[i] == nums[i-1]) continue;
33+
34+
int numI = nums[i];
35+
36+
int left = i + 1;
37+
int right = nums.length - 1;
38+
39+
// Time Complexity: O(N)
40+
while(left < right) {
41+
int numLeft = nums[left];
42+
int numRight = nums[right];
43+
44+
int sum = numI + numLeft + numRight;
45+
46+
if(sum == 0) {
47+
answers.add(Arrays.asList(numI, numLeft, numRight));
48+
49+
// skip same lefts and rights two prevent duplicate
50+
// * must update both left and right
51+
// * e.g. if only left is moved, newNumLeft = 0 - (numI + numRight) and that can only be numLeft that's already visited
52+
// * Time Complexity: O(1) because there is no actual operation other than skipping
53+
while(left < nums.length && nums[left] == numLeft) left++;
54+
55+
while(right > left && nums[right] == numRight) right--;
56+
} else if(sum > 0) {
57+
right--;
58+
} else {
59+
left++;
60+
}
61+
}
62+
}
63+
64+
return answers;
65+
}
66+
}

β€Ž3sum/unpo88.pyβ€Ž

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
class Solution:
2+
def threeSum(self, nums: list[int]) -> list[list[int]]:
3+
nums.sort()
4+
result = set()
5+
6+
for i in range(len(nums) - 2):
7+
# μ–‘μˆ˜μΈ 경우 더 이상 탐색할 ν•„μš”κ°€ μ—†μŒ
8+
if nums[i] > 0:
9+
break
10+
11+
# i 쀑볡 skip
12+
if i > 0 and nums[i] == nums[i - 1]:
13+
continue
14+
15+
left = i + 1
16+
right = len(nums) - 1
17+
18+
while left < right:
19+
total = nums[i] + nums[left] + nums[right]
20+
21+
if total == 0:
22+
result.add((nums[i], nums[left], nums[right]))
23+
24+
# 쀑볡 κ±΄λ„ˆλ›°κΈ°
25+
while left < right and nums[left] == nums[left + 1]:
26+
left += 1
27+
# 쀑볡 κ±΄λ„ˆλ›°κΈ°
28+
while left < right and nums[right] == nums[right - 1]:
29+
right -= 1
30+
left += 1
31+
right -= 1
32+
elif total < 0:
33+
left += 1
34+
else:
35+
right -= 1
36+
37+
return [list(t) for t in result]
38+
39+
40+
"""
41+
================================================================================
42+
풀이 κ³Όμ • - 10:51 μ‹œμž‘
43+
================================================================================
44+
45+
1. μ •μˆ˜ λ°°μ—΄ numsκ°€ μ£Όμ–΄μ§€λ©΄
46+
2. λͺ¨λ“  μ„Έ 쌍 [nums[i], nums[j], nums[k]]을 λ°˜ν™˜ν•΄μ•Όν•œλ‹€
47+
3. i != j, i != k, j != k μ—¬μ•Όν•˜κ³ 
48+
4. nums[i] + nums[j] + nums[k] == 0 μ΄μ–΄μ•Όν•œλ‹€
49+
5. μ€‘λ³΅λœ μ„Έ 쌍이 ν¬ν•¨λ˜μ§€ μ•Šμ•„μ•Όν•œλ‹€
50+
51+
52+
[1μ°¨ μ‹œλ„] Brute Force 3쀑 반볡문
53+
────────────────────────────────────────────────────────────────────────────────
54+
6. μ œμ•½μ„ λ¬΄μ‹œν•˜κ³  생각해보면 Brute Force 3쀑 반볡문으둜 찾을 수 μžˆμ„ 것 κ°™μŒ
55+
7. 쀑볡도 μ œκ±°ν•΄μ•Όν•˜λ‹ˆκΉŒ λ§ˆμ§€λ§‰μ— set을 두고 처리
56+
57+
result = []
58+
n = len(nums)
59+
60+
for i in range(n):
61+
for j in range(i+1, n):
62+
for k in range(j+1, n):
63+
if nums[i] + nums[j] + nums[k] == 0:
64+
triplet = sorted([nums[i], nums[j], nums[k]])
65+
if triplet not in result:
66+
result.append(triplet)
67+
68+
return result
69+
70+
8. Time Limit Exceeded λ°œμƒ
71+
9. O(nΒ³) μ‹œκ°„ λ³΅μž‘λ„λ‘œ λ„ˆλ¬΄ 느림
72+
73+
74+
[2μ°¨ μ‹œλ„] Two Sum μ‘μš© (HashSet)
75+
────────────────────────────────────────────────────────────────────────────────
76+
10. 3개λ₯Ό λ™μ‹œμ— μ°ΎμœΌλ €λ‹ˆκΉŒ μ–΄λ €μš΄ 것 같은데
77+
11. 2개λ₯Ό λ¨Όμ € κ΅¬ν•˜κ³ , λ‚˜λ¨Έμ§€ ν•˜λ‚˜λ₯Ό λ”ν•˜λ©΄ 0이 λ˜λŠ”μ§€λ₯Ό ν™•μΈν•΄λ³ΌκΉŒ
78+
12. 두 수의 ν•© = λ‚˜λ¨Έμ§€ ν•˜λ‚˜μ˜ κ°’
79+
13. -nums[i] = nums[j] + nums[k]
80+
14. 그럼 Two Sum 문제둜 ν’€ 수 μžˆμ„λ“―?
81+
15. 두 개의 합이 set에 μ‘΄μž¬ν•˜λŠ”μ§€λ₯Ό μ²΄ν¬ν•˜λŠ” ν˜•νƒœλ‘œ κ°€λ³΄μž
82+
83+
result = set()
84+
85+
for i in range(len(nums)):
86+
seen = set()
87+
for j in range(i + 1, len(nums)):
88+
complement = -(nums[i] + nums[j])
89+
if complement in seen:
90+
result.add(tuple(sorted([nums[i], nums[j], complement])))
91+
seen.add(nums[j])
92+
93+
return [list(x) for x in result]
94+
95+
16. μ•„ 근데 이것도 Time Limit Exceededκ°€ λ°œμƒν•˜λ„€
96+
17. O(nΒ²) μ‹œκ°„ λ³΅μž‘λ„λ‘œ κ°œμ„ ν–ˆμ§€λ§Œ sorted() 호좜과 set 연산이 μΆ”κ°€ λΉ„μš© λ°œμƒ
97+
18. λ‹€λ₯Έ μ ‘κ·Ό 방법이 ν•„μš”ν•  λ“―
98+
99+
100+
[3μ°¨ μ‹œλ„] Two Pointer 방식
101+
────────────────────────────────────────────────────────────────────────────────
102+
19. 그럼 Two Pointer λ°©μ‹μœΌλ‘œ ν’€μ–΄μ•Όν•  것 같은데
103+
20. Two Pointer 방식을 μ‚¬μš©ν•˜λ €λ©΄ 정렬이 ν•„μš”ν•¨
104+
21. Two Sum의 Two Pointer νŒ¨ν„΄μ„ μƒκ°ν•΄λ³΄μž
105+
22. 근데 3개λ₯Ό λ™μ‹œμ— 찾으렀면 μ–΄λ–»κ²Œ ν•΄μ•Όν• κΉŒ?
106+
23. iλ₯Ό κ³ μ •ν•˜κ³ , λ‚˜λ¨Έμ§€μ—μ„œ Two Sum으둜 합이 -nums[i]인 두 수λ₯Ό μ°ΎλŠ”λ‹€!
107+
108+
μ •λ ¬ μ „: [-1, 0, 1, 2, -1, -4]
109+
μ •λ ¬ ν›„: [-4, -1, -1, 0, 1, 2]
110+
index: 0 1 2 3 4 5
111+
112+
i = 0, left = i + 1, right = len(nums) - 1
113+
[-4, -1, -1, 0, 1, 2]
114+
i L R
115+
116+
i = 1:
117+
[-4, -1, -1, 0, 1, 2]
118+
i L R
119+
120+
25. μ •λ ¬ λ¨Όμ € ν•œ ν›„ ν•©μ˜ 크기에 따라 포인터λ₯Ό 이동
121+
122+
nums.sort()
123+
result = set()
124+
125+
for i in range(len(nums) - 2):
126+
left = i + 1
127+
right = len(nums) - 1
128+
129+
while left < right:
130+
total = nums[i] + nums[left] + nums[right]
131+
132+
if total == 0:
133+
result.add((nums[i], nums[left], nums[right]))
134+
left += 1
135+
right -= 1
136+
elif total < 0:
137+
left += 1
138+
else:
139+
right -= 1
140+
141+
return [list(t) for t in result]
142+
143+
25. O(nΒ²) μ‹œκ°„ λ³΅μž‘λ„ (μ •λ ¬ O(n log n) + 반볡문 O(nΒ²))
144+
26. μ •μƒμ μœΌλ‘œ ν†΅κ³Όλ˜λŠ” 것 확인 μ™„λ£Œ
145+
27. 근데 이 λ°©μ‹μœΌλ‘œ ν’€μ—ˆλŠ”λ° λŠλ¦¬λ‹€
146+
147+
148+
[4μ°¨ κ°œμ„ ] 쀑볡 제거 μ΅œμ ν™”
149+
────────────────────────────────────────────────────────────────────────────────
150+
28. Claudeμ—κ²Œ λ¬Όμ–΄λ³΄λ‹ˆ tuple 생성할 λ•Œ μƒμˆ˜ λ°°μˆ˜κ°€ 큰 것 κ°™λ‹€κ³  함
151+
29. 쀑볡을 미리 μŠ€ν‚΅ν•΄μ£ΌλŠ” 방법을 μ•Œλ €μ€Œ
152+
30. iκ°€ μ–‘μˆ˜μΈ 경우 더 이상 탐색할 ν•„μš” μ—†μŒ (μ •λ ¬λ˜μ–΄ μžˆμœΌλ―€λ‘œ)
153+
31. i, left, right 쀑볡 κ±΄λ„ˆλ›°κΈ° μΆ”κ°€
154+
155+
nums.sort()
156+
result = set()
157+
158+
for i in range(len(nums) - 2):
159+
# μ–‘μˆ˜μΈ 경우 더 이상 탐색할 ν•„μš”κ°€ μ—†μŒ
160+
if nums[i] > 0:
161+
break
162+
163+
# i 쀑볡 skip
164+
if i > 0 and nums[i] == nums[i - 1]:
165+
continue
166+
167+
left = i + 1
168+
right = len(nums) - 1
169+
170+
while left < right:
171+
total = nums[i] + nums[left] + nums[right]
172+
173+
if total == 0:
174+
result.add((nums[i], nums[left], nums[right]))
175+
176+
# 쀑볡 κ±΄λ„ˆλ›°κΈ°
177+
while left < right and nums[left] == nums[left + 1]:
178+
left += 1
179+
while left < right and nums[right] == nums[right - 1]:
180+
right -= 1
181+
left += 1
182+
right -= 1
183+
elif total < 0:
184+
left += 1
185+
else:
186+
right -= 1
187+
188+
return [list(t) for t in result]
189+
190+
32. 쀑볡 처리 μ΅œμ ν™”λ‘œ 속도 κ°œμ„ 
191+
33. μ΅œμ’… 톡과 확인 μ™„λ£Œ
192+
"""

β€Žclimbing-stairs/haxr369.javaβ€Ž

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
class Solution {
2+
/**
3+
* 계산 n개λ₯Ό 였λ₯΄κΈ° μœ„ν•΄ 1 λ˜λŠ” 2κ°œμ”© 였λ₯΄λŠ” λͺ¨λ“  경우의 수λ₯Ό κ΅¬ν•˜κΈ°
4+
*
5+
* DP문제 풀이 κ³Όμ •
6+
* 1. 문제 λ‹¨μˆœν™”
7+
* - 숫자 N을 λ§Œλ“€κΈ° μœ„ν•΄ 1 λ˜λŠ” 2λ₯Ό λ”ν•˜λŠ” μˆœμ„œλ₯Ό λ§Œλ“œλŠ” 경우의 수
8+
* 2. λ¬Έμ œμ—μ„œ μ›ν•˜λŠ” 것
9+
* - N을 λ§Œλ“€κΈ° μœ„ν•œ λͺ¨λ“  경우의 수
10+
* => DP[N] = N을 λ§Œλ“€κΈ° μœ„ν•œ λͺ¨λ“  경우의 수
11+
* 2. κ·œμΉ™ μ°ΎκΈ°
12+
* - N은 N-1μ—μ„œ 1 λ”ν•˜κ±°λ‚˜, N-2μ—μ„œ 2λ₯Ό λ”ν•˜λ©΄ 도달할 수 μžˆλ‹€.
13+
* - λ”°λΌμ„œ N에 λ„λ‹¬ν•˜κΈ° μœ„ν•œ 경우의 μˆ˜λŠ” N-1을 λ„λ‹¬ν•˜κΈ° μœ„ν•œ 경우의 수 + N-2에 λ„λ‹¬ν•˜κΈ° μœ„ν•œ 경우의 수
14+
* - DP[0] = 1 => 움직이지 μ•ŠλŠ”λ‹€λŠ” 경우의 수
15+
* - DP[1] = 1 => 1μΉΈ μ›€μ§μ΄λŠ” 경우의 수
16+
* - DP[N] = DP[N-2] + DP[N-1]
17+
*/
18+
public int climbStairs(int n) {
19+
/**
20+
* Runtime: 0 ms (Beats 100.00%)
21+
* Memory: 42.00 MB (Beats 15.00%)
22+
* Space Complexity: O(N)
23+
* - N 크기의 λ°°μ—΄ 1개 μ‚¬μš©μœΌλ‘œ O(N)
24+
* > O(N)
25+
* Time Complexity: O(N)
26+
* - N회 λ§μ…ˆμœΌλ‘œ => O(N)
27+
* > O(N)
28+
*/
29+
int[] dp = new int[n + 1];
30+
dp[0] = 1;
31+
dp[1] = 1;
32+
33+
for (int i = 2; i < n + 1; i++) {
34+
dp[i] = dp[i - 1] + dp[i - 2];
35+
}
36+
return dp[n];
37+
}
38+
}

0 commit comments

Comments
Β (0)