Skip to content

Commit d9f1e39

Browse files
author
이연수
committed
three sum
1 parent 5b8aa27 commit d9f1e39

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

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+
}

0 commit comments

Comments
 (0)