-
Notifications
You must be signed in to change notification settings - Fork 126
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'DaleStudy:main' into main
- Loading branch information
Showing
168 changed files
with
6,334 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
""" | ||
첫번째 풀이 -> 달레의 코드 풀이 | ||
1) sort와 two pointer를 활용한 풀이 | ||
2) has_set 을 활용한 중복 제거 | ||
두번째 풀이 -> Neetcode 풀이 | ||
1) sort와 two pointer를 활용한 풀이 | ||
2) while loop 를 활용한 중복 제거 | ||
Time: O(n^2) = O(n) * O(n) | ||
Space: O(n) | ||
""" | ||
|
||
|
||
class Solution: | ||
def threeSum(self, nums: List[int]) -> List[List[int]]: | ||
nums.sort() | ||
res = set() | ||
n = len(nums) | ||
|
||
for i in range(n): | ||
l, r = i + 1, n - 1 | ||
while l < r: | ||
summ = nums[i] + nums[l] + nums[r] | ||
if summ < 0: | ||
l += 1 | ||
elif summ > 0: | ||
r -= 1 | ||
else: | ||
res.add((nums[i], nums[l], nums[r])) | ||
l += 1 | ||
return list(res) | ||
|
||
|
||
class Solution: | ||
def threeSum(self, nums: List[int]) -> List[List[int]]: | ||
nums.sort() | ||
res = [] | ||
n = len(nums) | ||
|
||
for i in range(n): | ||
l, r = i + 1, n - 1 | ||
|
||
if i > 0 and nums[i] == nums[i - 1]: | ||
continue | ||
|
||
while l < r: | ||
summ = nums[i] + nums[l] + nums[r] | ||
if summ < 0: | ||
l += 1 | ||
elif summ > 0: | ||
r -= 1 | ||
else: | ||
res.append([nums[i], nums[l], nums[r]]) | ||
l += 1 | ||
while nums[l] == nums[l - 1] and l < r: | ||
l += 1 | ||
|
||
return res |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package leetcode_study | ||
|
||
/** | ||
* 주어진 배열의 세 원소의 합이 0인 경우를 구하는 문제. (세 개의 값의 결과는 중복되지 않음) | ||
* | ||
* 주어진 조건 | ||
* 3 <= nums.length <= 3000 | ||
* -105 <= nums[i] <= 105 | ||
*/ | ||
|
||
/** | ||
* case01. 조합을 사용한 풀이. | ||
* 시간 초과 발생 이유 | ||
* -> 모든 가능한 세 개의 조합을 생성하기 때문에 발생. | ||
* 시간 복잡도: | ||
* -> 세 개의 조합 생성 과정: O(n * (n-1) * (n-2)) / 3. 최악의 경우 n = 3000, 4.5 억개 조합 생성 | ||
* -> 세 개의 조합 결과 sorting 과정: O(klogk). k = 3 | ||
* -> 결과값을 필터링해 합이 0인 배열을 필터하는 과정: O(n) | ||
* 나머지 연산이 세 개의 조합 생성 과정에 영향을 받아 계산 횟수 증가. | ||
* | ||
* 공간 복잡도: | ||
* -> 각 조합을 모두 저장: O(n^3) | ||
*/ | ||
fun threeSumUseCombination(nums: IntArray): List<List<Int>> { | ||
// 결과를 담을 Set 자료구조 | ||
val processResult = mutableSetOf<List<Int>>() | ||
|
||
// 주어진 배열의 크기를 담는 변수 | ||
val maxNumber = nums.size | ||
|
||
// 조합 배열의 크기 | ||
val givenSize = 3 | ||
|
||
// 나타낼 인덱스를 구하는 배열 초기화 | ||
val indices = IntArray(givenSize) | ||
for (i in 0 until givenSize) { | ||
indices[i] = i | ||
} | ||
|
||
while (indices[givenSize - 1] < maxNumber) { | ||
processResult.add(indices.map { nums[it] }.sorted()) | ||
var i = givenSize - 1 | ||
|
||
while (i >= 0 && indices[i] == i + maxNumber - givenSize) { | ||
i-- | ||
} | ||
|
||
if (i >= 0) { | ||
indices[i]++ | ||
for (j in i + 1 until givenSize) { | ||
indices[j] = indices[j-1] + 1 | ||
} | ||
} else break | ||
} | ||
|
||
return processResult.filter { it.sum() == 0 } | ||
} | ||
|
||
/** | ||
* case02. 투 포인터를 사용한 풀이 | ||
* 조합을 사용한 풀이와 달리 시간 초과가 발생하지 않음. O(n^3)의 시간 복잡도를 O(n^2)으로 줄임 | ||
* | ||
* 시간 복잡도: | ||
* -> 주어진 숫자 배열 오름차순으로 정렬: O(nlogn) | ||
* -> 세 개의 숫자를 더하는 로직 | ||
* -> 외부 반복문을 통해 주어진 배열 전체 조회: O(n) | ||
* -> 내부 반복문을 통해 start to last index 순회: O(n) | ||
* -> O(n^2) | ||
* ∴ O(nlogn) + O(n^2) => O(n^2) | ||
* | ||
* 공간 복잡도: | ||
* -> 주어진 숫자 배열의 정렬을 담는 공간 필요: O(n) | ||
*/ | ||
fun threeSum(nums: IntArray): List<List<Int>> { | ||
val processResult = mutableListOf<List<Int>>() | ||
val sortedNums = nums.sorted() | ||
|
||
for (i in sortedNums.indices) { | ||
if (i > 0 && sortedNums[i] == sortedNums[i-1]) continue | ||
|
||
var startIndex = i + 1 | ||
var lastIndex = sortedNums.size - 1 | ||
|
||
while (startIndex < lastIndex) { | ||
val sum = sortedNums[i] + sortedNums[startIndex] + sortedNums[lastIndex] | ||
when { | ||
sum == 0 -> { | ||
processResult.add(listOf(sortedNums[i], sortedNums[startIndex], sortedNums[lastIndex])) | ||
while (startIndex < lastIndex && sortedNums[startIndex] == sortedNums[startIndex + 1]) startIndex++ | ||
while (startIndex < lastIndex && sortedNums[lastIndex] == sortedNums[lastIndex - 1]) lastIndex-- | ||
startIndex++ | ||
lastIndex-- | ||
} | ||
sum < 0 -> { | ||
startIndex++ | ||
} | ||
else -> { | ||
lastIndex-- | ||
} | ||
} | ||
} | ||
} | ||
return processResult | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// 이전에 투포인터를 활용하여 시도했지만 중복된 값들을 처리하는데 어려움이 있었습니다. | ||
// 그래서 해답을 보았고 새로운 방법으로 풀어보았습니다. | ||
// 서로 다른 i와 j 인덱스를 2중 for문으로 진행하면서 | ||
// i와 j사이 수들을 set으로 관리합니다. | ||
// set에 -nums[i]-nums[j]가 존재하면 결과 리스트에 추가합니다. | ||
// 시간복잡도 : O(N^2) | ||
// 공간복잡도 : O(N) | ||
class SolutionGotprgmer { | ||
public List<List<Integer>> threeSum(int[] nums) { | ||
// 결과를 저장할 리스트 | ||
List<List<Integer>> result = new ArrayList<>(); | ||
Set<Integer> set; | ||
Set<List<Integer>> resultSet = new HashSet<>(); | ||
List<Integer> numList; | ||
|
||
|
||
// 리스트 정렬 | ||
Arrays.sort(nums); | ||
for(int i=0;i<nums.length-2;i++){ | ||
if (i > 0 && nums[i - 1] == nums[i]) continue; | ||
|
||
set = new HashSet<>(); | ||
for(int j=i+1;j<nums.length;j++){ | ||
int checkNum = nums[i]+nums[j]; | ||
if(set.contains(-checkNum)){ | ||
numList = new ArrayList<>(Arrays.asList(nums[i], -checkNum, nums[j])); | ||
if(!resultSet.contains(numList)){ | ||
result.add(numList); | ||
resultSet.add(numList); | ||
} | ||
} | ||
set.add(nums[j]); | ||
} | ||
} | ||
return result; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
class Solution: | ||
def threeSum(self, nums: List[int]) -> List[List[int]]: | ||
answerSet = set() | ||
nums.sort() | ||
|
||
for i in range(len(nums) - 2): | ||
leftIdx = i + 1 | ||
rightIdx = len(nums) - 1 | ||
while leftIdx < rightIdx: | ||
sum = nums[i] + nums[leftIdx] + nums[rightIdx] | ||
if sum < 0: | ||
leftIdx += 1 | ||
elif sum > 0: | ||
rightIdx -= 1 | ||
else: | ||
answerSet.add((nums[i], nums[leftIdx], nums[rightIdx])) | ||
leftIdx = leftIdx + 1 | ||
rightIdx = rightIdx - 1 | ||
|
||
return list(answerSet) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/** | ||
* @param {number[]} nums | ||
* @return {number[][]} | ||
*/ | ||
|
||
|
||
// Time Complexity: O(n^2) | ||
// Space Complexity: O(n^2) | ||
|
||
var threeSum = function (nums) { | ||
|
||
const sorted = [...nums].sort((a, b) => a - b); | ||
|
||
let result = []; | ||
|
||
// Loop through the array and pick each number as the first number for the triplet | ||
for (let i = 0; i < sorted.length - 2; i++) { | ||
|
||
// skip duplicate values for sorted[middle] | ||
if(i > 0 && sorted[i - 1] === sorted[i]) { | ||
continue; | ||
} | ||
|
||
let left = i + 1; // Left pointer starts right after the current middle | ||
let right = sorted.length - 1; // Right pointer starts at the last element | ||
|
||
while (left < right) { | ||
const sum = sorted[i] + sorted[left] + sorted[right]; | ||
|
||
if (sum === 0) { | ||
result.push([sorted[left], sorted[i], sorted[right]]); | ||
|
||
// skip duplicates for sorted[left] and sorted[right] | ||
while(left < right && sorted[left] === sorted[left + 1]){ | ||
left += 1; // Move left pointer to the right to skip duplicate values | ||
} | ||
|
||
while(left < right && sorted[right] === sorted[right - 1]) { | ||
right -= 1; // Move right pointer to the left to skip duplicate values | ||
} | ||
|
||
left += 1; | ||
right -= 1; | ||
|
||
} else if (sum > 0) { | ||
right -= 1; | ||
|
||
} else { | ||
left += 1 | ||
} | ||
} | ||
} | ||
|
||
return result; | ||
|
||
}; | ||
|
||
|
||
// var threeSum = function (nums) { | ||
|
||
// i != j, i != k, and j != k can be interpreted as i < j < k | ||
|
||
// three nested loops | ||
// time complexity of O(n³) | ||
// Time Limit Exceeded | ||
|
||
// let result = []; | ||
|
||
// for (let i = 0; i < nums.length - 2; i++) { | ||
// for (let j = i + 1; j < nums.length - 1; j++) { | ||
// for (let k = j + 1; k < nums.length; k++) { | ||
// if (nums[i] + nums[j] + nums[k] === 0) { | ||
// const str = [nums[i], nums[j], nums[k]].sort((a, b) => a - b).join(",") | ||
// result.push(str) | ||
// } | ||
// } | ||
// } | ||
|
||
// } | ||
|
||
// result = [... new Set(result)].map(str => str.split(",").map(str => +str)) | ||
|
||
// return result; | ||
|
||
// } | ||
|
Oops, something went wrong.