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 e44814c

Browse files
authoredJun 2, 2024
Merge branch 'DaleStudy:main' into main
2 parents ebb5f61 + c9fe566 commit e44814c

File tree

30 files changed

+1064
-0
lines changed

30 files changed

+1064
-0
lines changed
 

‎3sum/Leo.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
class Solution:
2+
def threeSum(self, nums: List[int]) -> List[List[int]]:
3+
4+
nums.sort()
5+
res = []
6+
7+
for i, ch in enumerate(nums):
8+
if i > 0 and nums[i] == nums[i - 1]: continue
9+
10+
l, r = i + 1, len(nums) - 1
11+
while l < r:
12+
threeSum = ch + nums[l] + nums[r]
13+
14+
if threeSum < 0:
15+
l += 1
16+
elif threeSum > 0:
17+
r -= 1
18+
else:
19+
res.append([ch, nums[l], nums[r]])
20+
l += 1
21+
while l < r and nums[l] == nums[l - 1]:
22+
l += 1
23+
24+
return res
25+
26+
## TC: O(n^2), SC: O(1)

‎3sum/bhyun-kim.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
"""
2+
15. 3Sum
3+
https://leetcode.com/problems/3sum/description/
4+
5+
Solution:
6+
- Sort the list
7+
- Iterate through the list
8+
- For each element, find the two elements that sum up to -element
9+
- Use two pointers to find the two elements
10+
- Skip the element if it is the same as the previous element
11+
- Skip the two elements if they are the same as the previous two elements
12+
- Add the set to the output list
13+
14+
Example:
15+
-----------------------------------------
16+
low : |
17+
high: |
18+
i : |
19+
[-4,-1,-1,0,1,2]
20+
21+
-----------------------------------------
22+
low : |
23+
high: |
24+
i : |
25+
[-4,-1,-1,0,1,2]
26+
27+
... no possible set with i=-4, and high=2
28+
29+
-----------------------------------------
30+
low : |
31+
high: |
32+
i : |
33+
[-4,-1,-1,0,1,2]
34+
35+
36+
Time complexity: O(n^2)
37+
- O(nlogn) for sorting
38+
- O(n^2) for iterating through the list and finding the two elements
39+
- Total: O(n^2)
40+
Space complexity: O(n)
41+
- O(n) for the output list
42+
- O(n) for the prevs dictionary
43+
- O(n) for the prevs_n set
44+
- Total: O(n)
45+
"""
46+
47+
48+
from typing import List
49+
50+
51+
class Solution:
52+
def threeSum(self, nums: List[int]) -> List[List[int]]:
53+
nums = sorted(nums)
54+
output = []
55+
prevs = dict()
56+
prevs_n = set()
57+
58+
for i in range(len(nums) - 2):
59+
n_i = nums[i]
60+
61+
if n_i in prevs_n:
62+
continue
63+
else:
64+
prevs_n.add(n_i)
65+
66+
low, high = i + 1, len(nums) - 1
67+
while low < high:
68+
n_low = nums[low]
69+
n_high = nums[high]
70+
if n_i + n_low + n_high == 0:
71+
if not f"[{n_i},{n_low},{n_high}]" in prevs:
72+
prevs[f"[{n_i},{n_low},{n_high}]"] = 1
73+
output.append([n_i, n_low, n_high])
74+
low += 1
75+
high -= 1
76+
77+
elif n_i + n_low + n_high < 0:
78+
low += 1
79+
80+
elif n_i + n_low + n_high > 0:
81+
high -= 1
82+
83+
return output

‎3sum/evan.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* @param {number[]} nums
3+
* @return {number[][]}
4+
*/
5+
var threeSum = function (nums) {
6+
const sorted = nums.sort((a, b) => a - b);
7+
const result = [];
8+
9+
for (let i = 0; i < sorted.length; i++) {
10+
const fixedNumber = sorted[i];
11+
const previousFixedNumber = sorted[i - 1];
12+
13+
if (fixedNumber === previousFixedNumber) {
14+
continue;
15+
}
16+
17+
let [leftEnd, rightEnd] = [i + 1, sorted.length - 1];
18+
19+
while (leftEnd < rightEnd) {
20+
const sum = fixedNumber + sorted[leftEnd] + sorted[rightEnd];
21+
22+
if (sum === 0) {
23+
result.push([sorted[leftEnd], sorted[rightEnd], sorted[i]]);
24+
25+
while (
26+
sorted[leftEnd + 1] === sorted[leftEnd] ||
27+
sorted[rightEnd - 1] === sorted[rightEnd]
28+
) {
29+
if (sorted[leftEnd + 1] === sorted[leftEnd]) {
30+
leftEnd += 1;
31+
}
32+
33+
if (sorted[rightEnd - 1] === sorted[rightEnd]) {
34+
rightEnd -= 1;
35+
}
36+
}
37+
38+
leftEnd += 1;
39+
rightEnd -= 1;
40+
} else if (sum < 0) {
41+
leftEnd += 1;
42+
} else {
43+
rightEnd -= 1;
44+
}
45+
}
46+
}
47+
48+
return result;
49+
};
50+
51+
/**
52+
* Time Complexity: O(n^2)
53+
* The algorithm involves sorting the input array, which takes O(n log n) time.
54+
* The main part of the algorithm consists of a loop that runs O(n) times, and within that loop, there is a two-pointer technique that runs in O(n) time.
55+
* Thus, the overall time complexity is O(n log n) + O(n^2), which simplifies to O(n^2).
56+
*
57+
* Space Complexity: O(n)
58+
* The space complexity is O(n) due to the space needed for the sorted array and the result array.
59+
* Although the sorting algorithm may require additional space, typically O(log n) for the in-place sort in JavaScript, the dominant term is O(n) for the result storage.
60+
*/

‎3sum/invidam.go.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Intuition
2+
예전에 풀어봤던 문제였어서 접근법을 알고있었다.
3+
4+
# Approach
5+
1. 정렬을 하여 배열의 대소관계를 일정하게 한다.
6+
2. i,j,k를 설정해야 하는데, i < j < k이도록 한다.
7+
3. i는 맨 앞에서부터 순회한다.
8+
4. j는 i의 뒤부터 순회한다.
9+
5. k는 맨 뒤에서부터 순회한다.
10+
6. 세 인덱스가 가리키는 값들의 합을 비교하여 j와 k를 수정한다.
11+
12+
# Complexity
13+
- Time complexity: $$O(n^2)$$
14+
- 입력 배열의 길이 n에 대하여, `i`, `j와 k`를 순회한다.
15+
16+
- Space complexity: $$O(n)$$
17+
- 입력으로 들어온 배열의 길이 n에 대하여, 생성하는 결과 배열의 길이 역시 이와 동일하다.
18+
# Code
19+
20+
```go
21+
func update(i int, j int, k int, sum int, nums []int) (int, int) {
22+
if sum <= 0 {
23+
j++
24+
for j < len(nums) && j >= 1 && nums[j] == nums[j-1] {
25+
j++
26+
}
27+
} else {
28+
k--
29+
for k >= 0 && k+1 < len(nums) && nums[k] == nums[k+1] {
30+
k--
31+
}
32+
}
33+
34+
return j, k
35+
}
36+
37+
func threeSum(nums []int) [][]int {
38+
var triplets [][]int
39+
40+
sort.Ints(nums)
41+
for i := 0; i < len(nums); i++ {
42+
j, k := i+1, len(nums)-1
43+
44+
if i != 0 && nums[i-1] == nums[i] {
45+
continue
46+
}
47+
48+
for j < k {
49+
sum := nums[i] + nums[j] + nums[k]
50+
if sum == 0 {
51+
triplets = append(triplets, []int{nums[i], nums[j], nums[k]})
52+
}
53+
j, k = update(i, j, k, sum, nums)
54+
}
55+
}
56+
return triplets
57+
}
58+
59+
```

‎3sum/samthekorean.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# O(n^2) where there is nested loop.
2+
# O(1) where high and low are reused as constant values.
3+
4+
5+
class Solution:
6+
def threeSum(self, nums: List[int]) -> List[List[int]]:
7+
# Initialize a set to store unique triplets
8+
triplets = set()
9+
10+
# Sort the list to make two-pointer approach possible
11+
nums.sort()
12+
13+
# Iterate through the list, considering each element as a potential first element of a triplet
14+
for i in range(len(nums) - 2):
15+
low = i + 1
16+
high = len(nums) - 1
17+
18+
# To avoid duplicate iteration
19+
while low < high:
20+
three_sum = nums[i] + nums[low] + nums[high]
21+
22+
if three_sum < 0:
23+
low += 1
24+
elif three_sum > 0:
25+
high -= 1
26+
else:
27+
triplets.add((nums[i], nums[low], nums[high]))
28+
low += 1
29+
high -= 1

‎container-with-most-water/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- 문제: https://leetcode.com/problems/container-with-most-water/
2+
- 풀이: https://www.algodale.com/problems/container-with-most-water/

‎encode-and-decode-strings/Leo.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
class Codec:
2+
def encode(self, strs: List[str]) -> str:
3+
"""Encodes a list of strings to a single string.
4+
"""
5+
res = ''
6+
7+
for s in strs:
8+
res += str(len(s)) + '#' + s
9+
10+
return res
11+
12+
def decode(self, s: str) -> List[str]:
13+
"""Decodes a single string to a list of strings.
14+
"""
15+
res = []
16+
17+
i = 0
18+
while i < len(s):
19+
a = s.find('#', i)
20+
length = int(s[i:a])
21+
res.append(s[a + 1:a + 1 + length])
22+
i = a + 1 + length
23+
24+
return res
25+
26+
## TC: O(n), SC:O(n),n denotes sum of all len(s)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""
2+
271. Encode and Decode Strings
3+
https://leetcode.com/problems/encode-and-decode-strings/description/
4+
5+
Solution:
6+
- Concatenate the strings with a special character
7+
- Split the string by the special character
8+
9+
Time complexity: O(n)
10+
- Concatenating the strings: O(n)
11+
- Splitting the string: O(n)
12+
- Total: O(n)
13+
14+
Space complexity: O(n)
15+
- Storing the output: O(n)
16+
- Total: O(n)
17+
"""
18+
from typing import List
19+
20+
21+
class Codec:
22+
def encode(self, strs: List[str]) -> str:
23+
"""Encodes a list of strings to a single string."""
24+
output = strs[0]
25+
26+
for i in range(1, len(strs)):
27+
output += "é" + strs[i]
28+
29+
return output
30+
31+
def decode(self, s: str) -> List[str]:
32+
"""Decodes a single string to a list of strings."""
33+
34+
return s.split("é")

‎encode-and-decode-strings/evan.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
const DELIMITER = "#";
2+
3+
/**
4+
*
5+
* @param {string[]} strs
6+
* @returns {string}
7+
*/
8+
function encode(strs) {
9+
return strs.map((s) => `${s.length}${DELIMITER}${s}`).join("");
10+
}
11+
12+
/**
13+
*
14+
* @param {string} encodedStr
15+
* @returns {string[]}
16+
*/
17+
function decode(encodedStr) {
18+
const decodedStrings = [];
19+
let currentIndex = 0;
20+
21+
while (currentIndex < encodedStr.length) {
22+
let delimiterIndex = currentIndex;
23+
24+
while (encodedStr[delimiterIndex] !== DELIMITER) {
25+
delimiterIndex += 1;
26+
}
27+
28+
const strLength = parseInt(
29+
encodedStr.substring(currentIndex, delimiterIndex)
30+
);
31+
32+
decodedStrings.push(
33+
encodedStr.substring(delimiterIndex + 1, delimiterIndex + 1 + strLength)
34+
);
35+
36+
currentIndex = delimiterIndex + 1 + strLength;
37+
}
38+
39+
return decodedStrings;
40+
}
41+
/**
42+
* Time Complexity: O(n) where n is the length of the encoded string.
43+
* Reason:
44+
* The inner operations (finding # and extracting substrings) are proportional to the size of the encoded segments
45+
* but are ultimately bounded by the total length of the input string.
46+
*
47+
* Space Complexity: O(k) where k is the total length of the decoded strings.
48+
*/
49+
50+
/**
51+
* Test cases
52+
*/
53+
const strs4 = ["longestword", "short", "mid", "tiny"];
54+
const encoded4 = encode(strs4);
55+
console.log(encoded4); // Output: "11#longestword5#short3#mid4#tiny"
56+
57+
const decoded4 = decode(encoded4);
58+
console.log(decoded4); // Output: ["longestword", "short", "mid", "tiny"]
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Intuition
2+
구분자를 넣어 오류를 방지한다.
3+
# Approach
4+
<!-- Describe your approach to solving the problem. -->
5+
1. UTF-8에 벗어나는 구분자 ``을 넣어 구분했다.
6+
# Complexity
7+
- Time complexity: $$O(n)$$
8+
- 문자열의 길이 n에 대하여, 이를 순회하는 비용이 발생한다.
9+
10+
- Space complexity: $$O(n)$$
11+
- 문자열의 길이 n에 대하여, `encoded`를 만드는 공간이 발생한다.
12+
13+
# Code
14+
```go
15+
const DIVIDE_CHAR_V1 = ''
16+
func encodeV1(strs []string) string {
17+
ret := strings.Join(strs, string(DIVIDE_CHAR_V1))
18+
return ret
19+
}
20+
21+
func decodeV1(encoded string) []string {
22+
sep := string(DIVIDE_CHAR_V1)
23+
return strings.Split(encoded, sep)
24+
}
25+
```
26+
- - -
27+
# Intuition
28+
솔루션에서 네트워크 통신을 위한다는 목적을 듣고 수정해보았다. (유니코드를 넣는 게 의도는 아닌 듯했다.)
29+
# Approach
30+
1. 구분자 (`-`)와 이전 문자의 길이를 함께 저장한다.
31+
2. 구분자가 나온다면, 문자열의 길이를 추출하여 문자열을 디코딩한다.
32+
3. 위 과정을 배열을 순회하며 반복한다.
33+
# Complexity
34+
- Time complexity: $$O(n)$$
35+
- 문자열의 길이 n에 대하여, 이를 순회하는 비용이 발생한다.
36+
37+
- Space complexity: $$O(n)$$
38+
- 문자열의 길이 n에 대하여, `encoded`를 만드는 공간이 발생한다.
39+
40+
# Code
41+
```go
42+
const DIVIDE_CHAR = '-'
43+
func encode(strs []string) string {
44+
ret := ""
45+
for _, str := range strs {
46+
ret += str
47+
ret += fmt.Sprintf("%c%04d", DIVIDE_CHAR, len(str))
48+
// a-1bcd-3
49+
}
50+
return ret
51+
}
52+
53+
func decode(encoded string) []string {
54+
ret := make([]string, 0)
55+
for i := 0; i < len(encoded); {
56+
if encoded[i] == DIVIDE_CHAR {
57+
lenStr := encoded[i+1 : i+5]
58+
len, _ := strconv.Atoi(lenStr)
59+
60+
decodeStr := encoded[i-len : i]
61+
ret = append(ret, decodeStr)
62+
i += 5
63+
} else {
64+
i += 1
65+
}
66+
}
67+
68+
return ret
69+
}
70+
```
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
class Solution:
2+
"""
3+
@param: strs: a list of strings
4+
@return: encodes a list of strings to a single string.
5+
"""
6+
7+
# TC : O(n) where n is the combined length of the string in the list of strings.
8+
# SC : O(S), where S is the sum of the lengths of all strings in strs
9+
def encode(self, strs):
10+
res = ""
11+
for s in strs:
12+
res += str(len(s)) + ":" + s
13+
return res
14+
15+
"""
16+
@param: str: A string
17+
@return: decodes a single string to a list of strings
18+
"""
19+
20+
# TC : O(n) where n is the length of encoded string
21+
# SC : O(S), where S is the total length of the decoded strings.
22+
def decode(self, str):
23+
res, i = [], 0
24+
25+
while i < len(str):
26+
j = i
27+
while str[j] != ":":
28+
j += 1
29+
length = int(str[i:j])
30+
res.append(str[j + 1 : j + length + 1])
31+
i = j + 1 + length
32+
33+
return res
34+
35+
36+
def test_solution():
37+
solution = Solution()
38+
39+
# Test case 1: Basic test case
40+
input_strs = ["hello", "world"]
41+
encoded = solution.encode(input_strs)
42+
decoded = solution.decode(encoded)
43+
print(f"Test case 1\nEncoded: {encoded}\nDecoded: {decoded}\n")
44+
45+
# Test case 2: Empty list
46+
input_strs = []
47+
encoded = solution.encode(input_strs)
48+
decoded = solution.decode(encoded)
49+
print(f"Test case 2\nEncoded: {encoded}\nDecoded: {decoded}\n")
50+
51+
# Test case 3: List with empty strings
52+
input_strs = ["", "", ""]
53+
encoded = solution.encode(input_strs)
54+
decoded = solution.decode(encoded)
55+
print(f"Test case 3\nEncoded: {encoded}\nDecoded: {decoded}\n")
56+
57+
# Test case 4: List with mixed empty and non-empty strings
58+
input_strs = ["abc", "", "def"]
59+
encoded = solution.encode(input_strs)
60+
decoded = solution.decode(encoded)
61+
print(f"Test case 4\nEncoded: {encoded}\nDecoded: {decoded}\n")
62+
63+
# Test case 5: List with special characters
64+
input_strs = ["he:llo", "wo:rld"]
65+
encoded = solution.encode(input_strs)
66+
decoded = solution.decode(encoded)
67+
print(f"Test case 5\nEncoded: {encoded}\nDecoded: {decoded}\n")
68+
69+
70+
test_solution()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- 문제: https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/
2+
- 풀이: https://www.algodale.com/problems/find-minimum-in-rotated-sorted-array/

‎longest-consecutive-sequence/Leo.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class Solution:
2+
def longestConsecutive(self, nums: List[int]) -> int:
3+
4+
seen = set(nums)
5+
longest = 0
6+
7+
for n in seen:
8+
if (n - 1) not in seen:
9+
length = 1
10+
11+
while (n + length) in seen:
12+
length += 1
13+
14+
longest = max(length, longest)
15+
16+
return longest
17+
18+
## TC: O(n), SC: O(n)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""
2+
128. Longest Consecutive Sequence
3+
https://leetcode.com/problems/longest-consecutive-sequence/description/
4+
5+
Solution:
6+
- Create a set of the input list
7+
- Iterate through the set
8+
- For each element, find the consecutive elements
9+
- Use a while loop to find the consecutive elements
10+
- Update the longest length
11+
12+
Time complexity: O(n)
13+
- O(n) for iterating through the set
14+
15+
Space complexity: O(n)
16+
- O(n) for the set
17+
- Total: O(n)
18+
19+
"""
20+
21+
from typing import List
22+
23+
24+
class Solution:
25+
def longestConsecutive(self, nums: List[int]) -> int:
26+
longest_len = 0
27+
nums_set = set(nums)
28+
29+
for n in nums_set:
30+
if n - 1 not in nums_set:
31+
current_n = n
32+
current_len = 1
33+
34+
while current_n + 1 in nums_set:
35+
current_n += 1
36+
current_len += 1
37+
38+
longest_len = max(longest_len, current_len)
39+
40+
return longest_len

‎longest-consecutive-sequence/evan.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* @param {number[]} nums
3+
* @return {number}
4+
*/
5+
var longestConsecutive = function (nums) {
6+
const set = new Set(nums);
7+
let longestStreak = 0;
8+
9+
for (const num of set) {
10+
// Check if it's the start of a sequence
11+
if (!set.has(num - 1)) {
12+
let currentNum = num;
13+
let currentStreak = 1;
14+
15+
// Find the length of the sequence
16+
while (set.has(currentNum + 1)) {
17+
currentNum += 1;
18+
currentStreak += 1;
19+
}
20+
21+
longestStreak = Math.max(longestStreak, currentStreak);
22+
}
23+
}
24+
25+
return longestStreak;
26+
};
27+
28+
/**
29+
* Time Complexity: O(n) where n is the length of the input array.
30+
* Reason:
31+
* Creating the Set: O(n)
32+
* Iterating Through the Set: O(n)
33+
* Checking for the Start of a Sequence: O(n)
34+
* Finding the Length of the Sequence: O(n) across all sequences
35+
* Tracking the Longest Sequence: O(n)
36+
*
37+
* Space Complexity: O(n) because of the additional space used by the set.
38+
*/
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Intuition
2+
자기 자신 이후에 몇 개가 연속되었는지를 `dp`로 저장한다.
3+
# Approach
4+
1. 등장 여부를 `appear`에 기록한다.
5+
2. 자기 자신 이후 연속된 원소의 개수를 반환하는 함수를 만들고 매 배열마다 이를 호출한다.
6+
- `dp`로써, 자기 자신(`from`)에 따른 결과들을 유지한다.
7+
- 자기 자신이 등장했는지 여부에 따라 `0` 혹은 `다음 연속 개수 + 1`을 반환한다.
8+
3. 호출 결과 중 최대를 찾아 반환한다.
9+
# Complexity
10+
- Time complexity: $$O(nlog(n))$$
11+
12+
- Space complexity: $$O(n+m)$$
13+
# Code
14+
## Original
15+
```go
16+
func longestConsecutiveFrom(num int, appear map[int]bool, cache map[int]int) (ret int) {
17+
if val, ok := cache[num]; ok {
18+
return val
19+
}
20+
21+
if _, ok := appear[num]; ok {
22+
ret = longestConsecutiveFrom(num+1, appear, cache) + 1
23+
} else {
24+
ret = 0
25+
}
26+
cache[num] = ret
27+
return ret
28+
}
29+
30+
func longestConsecutive(nums []int) int {
31+
appear := make(map[int]bool, len(nums)/2)
32+
cache := make(map[int]int, len(nums)/2)
33+
for _, num := range nums {
34+
appear[num] = true
35+
}
36+
37+
var max int
38+
39+
for _, num := range nums {
40+
ret := longestConsecutiveFrom(num, appear, cache)
41+
if ret > max {
42+
max = ret
43+
}
44+
}
45+
return max
46+
}
47+
```
48+
49+
## Bottom-up
50+
```go
51+
func longestConsecutive(nums []int) int {
52+
appear := make(map[int]bool, len(nums)/2)
53+
for _, num := range nums {
54+
appear[num] = true
55+
}
56+
57+
var max int
58+
59+
for _, num := range nums {
60+
if appear[num-1] {
61+
continue
62+
}
63+
len := 1
64+
for appear[num+len] {
65+
len++
66+
}
67+
68+
if len > max {
69+
max = len
70+
}
71+
}
72+
return max
73+
}
74+
75+
```
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# TC : O(n) where n is the length of nums
2+
# SC : O(n) where n is the size of nums
3+
class Solution:
4+
def longestConsecutive(self, nums: List[int]) -> int:
5+
numSet = set(nums)
6+
longest = 0
7+
8+
for n in nums:
9+
# check whether its the start of the sequence
10+
if (n - 1) not in numSet:
11+
length = 0
12+
while (n + length) in numSet:
13+
length += 1
14+
longest = max(length, longest)
15+
return longest
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- 문제: https://leetcode.com/problems/longest-repeating-character-replacement/
2+
- 풀이: https://www.algodale.com/problems/longest-repeating-character-replacement/
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- 문제: https://leetcode.com/problems/longest-substring-without-repeating-characters/
2+
- 풀이: https://www.algodale.com/problems/longest-substring-without-repeating-characters/

‎product-of-array-except-self/Leo.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Solution:
2+
def productExceptSelf(self, nums: List[int]) -> List[int]:
3+
length = len(nums)
4+
res = [1] * length
5+
ltor = 1
6+
rtol = 1
7+
8+
for i in range(length):
9+
res[i] *= ltor
10+
ltor = ltor * nums[i]
11+
res[length - i - 1] *= rtol
12+
rtol = rtol * nums[length - i - 1]
13+
14+
return res
15+
16+
## TC: O(n), SC: O(1)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"""
2+
238. Product of Array Except Self
3+
https://leetcode.com/problems/product-of-array-except-self/description/
4+
5+
Solution:
6+
- Create two lists to store the product of elements from the left and right
7+
- Multiply the elements from the left and right lists to get the output
8+
9+
Example:
10+
nums = [4, 2, 3, 1, 7, 0, 9, 10]
11+
12+
left is numbers to the left of the current index
13+
right is numbers to the right of the current index
14+
from_left is the product of the numbers to the left of the current index
15+
from_right is the product of the numbers to the right of the current index
16+
17+
i = 0: (4) 2 3 1 7 0 9 10
18+
i = 1: 4 (2) 3 1 7 0 9 10
19+
i = 2: 4 2 (3) 1 7 0 9 10
20+
i = 3: 4 2 3 (1) 7 0 9 10
21+
i = 4: 4 2 3 1 (7) 0 9 10
22+
i = 5: 4 2 3 1 7 (0) 9 10
23+
i = 6: 4 2 3 1 7 0 (9) 10
24+
i = 7: 4 2 3 1 7 0 9 (10)
25+
26+
from_left = [0, 4, 8, 24, 24, 168, 0, 0]
27+
from_right = [0, 0, 0, 0, 0, 90, 10, 0]
28+
output = [0, 0, 0, 0, 0, 15120, 0, 0]
29+
30+
Time complexity: O(n)
31+
- Calculating the product of the elements from the left: O(n)
32+
- Calculating the product of the elements from the right: O(n)
33+
- Calculating the output: O(n)
34+
- Total: O(n)
35+
36+
Space complexity: O(n)
37+
- Storing the product of the elements from the left: O(n)
38+
- Storing the product of the elements from the right: O(n)
39+
- Storing the output: O(n)
40+
"""
41+
from typing import List
42+
43+
44+
class Solution:
45+
def productExceptSelf(self, nums: List[int]) -> List[int]:
46+
output = [0] * len(nums)
47+
48+
from_left = [0] * (len(nums))
49+
from_right = [0] * (len(nums))
50+
51+
from_left[0] = nums[0]
52+
from_right[-1] = nums[-1]
53+
54+
for i in range(1, len(nums) - 1):
55+
from_left[i] = from_left[i - 1] * nums[i]
56+
57+
for i in reversed(range(1, len(nums) - 1)):
58+
from_right[i] = from_right[i + 1] * nums[i]
59+
60+
output[0] = from_right[1]
61+
output[-1] = from_left[-2]
62+
for i in range(1, len(nums) - 1):
63+
output[i] = from_left[i - 1] * from_right[i + 1]
64+
65+
return output

‎product-of-array-except-self/evan.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* @param {number[]} nums
3+
* @return {number[]}
4+
*/
5+
var productExceptSelf = function (nums) {
6+
const length = nums.length;
7+
const result = Array(length).fill(1);
8+
9+
let leftProduct = 1;
10+
for (let i = 0; i < length; i++) {
11+
result[i] = leftProduct;
12+
leftProduct *= nums[i];
13+
}
14+
15+
let rightProduct = 1;
16+
for (let i = length - 1; i >= 0; i--) {
17+
result[i] *= rightProduct;
18+
rightProduct *= nums[i];
19+
}
20+
21+
return result;
22+
};
23+
24+
/**
25+
* Time Complexity: O(n)
26+
* The algorithm iterates through the nums array twice (two separate loops), each taking O(n) time.
27+
* Hence, the overall time complexity is O(2n), which simplifies to O(n).
28+
*
29+
* Space Complexity: O(1)
30+
* The algorithm uses a constant amount of extra space for the leftProduct and rightProduct variables.
31+
* The result array is not considered extra space as it is required for the output.
32+
* Therefore, the extra space complexity is O(1).
33+
*/
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Intuition
2+
0의 등장 횟수에 따라 경우의 수가 달라진다. 이를 이용한다.
3+
# Approach
4+
(사이트에서 Wrong Case를 제공하였기에 다양한 경우의 수를 대응할 수 있었다, 좋은 풀이는 아니라고 생각한다.)
5+
- 모든 수의 곱을 계산한 후, 배열을 순회하며 자기 자신을 나눈 값을 저장한다.
6+
- 0이 등장한 경우, 0이 아닌 배열의 원소들은 무조건 0을 저장해야 한다.
7+
- `golang`의 경우 `int`의 기본값이 0이라 아무것도 안해주면 된다.
8+
- 0이 2회 이상 등장한 경우, 모든 원소는 0이 된다.
9+
- `golang`의 경우 길이만 선언된 `int` 배열을 반환하면 된다.
10+
# Complexity
11+
- Time complexity: $$O(n)$$
12+
- 배열의 길이 n에 대하여, 순회하는 비용 n이 발생한다.
13+
14+
- Space complexity: $$O(n)$$
15+
- 배열의 길이 n에 대하여, 결과를 저장할 배열의 크기 n이 소모된다.
16+
# Code
17+
```go
18+
func productExceptSelf(nums []int) []int {
19+
answer := make([]int, len(nums))
20+
product := 1
21+
zeroCnt := 0
22+
for _, num := range nums {
23+
if num == 0 {
24+
zeroCnt++
25+
continue
26+
}
27+
product *= num
28+
}
29+
30+
if zeroCnt >= 2 {
31+
product = 0
32+
}
33+
34+
for i, num := range nums {
35+
if num == 0 {
36+
answer[i] = product
37+
} else if zeroCnt == 0 {
38+
answer[i] = product / num
39+
}
40+
}
41+
return answer
42+
}
43+
```
44+
# 여담
45+
부분곱문제로 해결하기 적합하다는 생각이 들었으나, `0`처리 때문에 시도해보진 않았다.
46+
솔루션들을 보며 좌, 우에 대해 2번을 사용하는 방법이 있다는 걸 알게되었다.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# TC : O(n)
2+
# SC : O(1)
3+
4+
5+
class Solution:
6+
def productExceptSelf(self, nums: List[int]) -> List[int]:
7+
ans = [1] * (len(nums))
8+
9+
prefix = 1
10+
for i in range(len(nums)):
11+
ans[i] = prefix
12+
prefix *= nums[i]
13+
postfix = 1
14+
for i in range(len(nums) - 1, -1, -1):
15+
ans[i] *= postfix
16+
postfix *= nums[i]
17+
18+
return ans
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- 문제: https://leetcode.com/problems/search-in-rotated-sorted-array/
2+
- 풀이: https://www.algodale.com/problems/search-in-rotated-sorted-array/

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class Solution:
2+
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
3+
4+
num_dict = collections.Counter(nums)
5+
freq = num_dict.most_common()
6+
ans = []
7+
8+
for key, val in freq:
9+
if k == 0:
10+
break
11+
12+
ans.append(key)
13+
k -= 1
14+
15+
return ans
16+
17+
## TC: O(n * logn), SC: O(n)

‎top-k-frequent-elements/bhyun-kim.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"""
2+
347. Top K Frequent Elements
3+
https://leetcode.com/problems/top-k-frequent-elements/description/
4+
5+
Solution:
6+
- Count the frequency of each element in the list
7+
- Sort the dictionary by the frequency in descending order
8+
- Return the first k elements in the sorted dictionary
9+
10+
Time complexity: O(nlogn)
11+
- Counting the frequency of each element: O(n)
12+
- Sorting the dictionary: O(nlogn)
13+
- Returning the first k elements: O(k)
14+
k <= n
15+
- Total: O(nlogn)
16+
17+
Space complexity: O(n)
18+
- Storing the frequency of each element: O(n)
19+
- Storing the sorted dictionary: O(n)
20+
- Storing the output: O(k)
21+
k <= n
22+
"""
23+
from collections import OrderedDict
24+
from typing import List
25+
26+
27+
class Solution:
28+
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
29+
n_dict = OrderedDict()
30+
31+
for n in nums:
32+
if n in n_dict:
33+
n_dict[n] += 1
34+
else:
35+
n_dict[n] = 1
36+
37+
n_dict = sorted(n_dict.items(), key=lambda x: x[1], reverse=True)
38+
39+
output = [0] * k
40+
for i in range(k):
41+
output[i] = n_dict[i][0]
42+
43+
return output

‎top-k-frequent-elements/evan.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* @param {number[]} nums
3+
* @param {number} k
4+
* @return {number[]}
5+
*/
6+
var topKFrequent = function (nums, k) {
7+
const counter = new Map();
8+
9+
nums.forEach((num) => {
10+
if (counter.has(num)) {
11+
counter.set(num, counter.get(num) + 1);
12+
} else {
13+
counter.set(num, 1);
14+
}
15+
});
16+
17+
const sorted = [...counter.entries()].sort(
18+
([, freqA], [, freqB]) => freqB - freqA
19+
);
20+
21+
return sorted.slice(0, k).map(([num]) => num);
22+
};
23+
24+
/**
25+
* Time Complexity: O(n log n)
26+
* - Counting the frequency of each element takes O(n) time.
27+
* - Sorting the entries by frequency takes O(n log n) time.
28+
* - Extracting the top k elements and mapping them takes O(k) time.
29+
* - Therefore, the overall time complexity is dominated by the sorting step, resulting in O(n log n).
30+
31+
* Space Complexity: O(n)
32+
* - The counter map requires O(n) space to store the frequency of each element.
33+
* - The sorted array also requires O(n) space.
34+
* - Therefore, the overall space complexity is O(n).
35+
*/

‎top-k-frequent-elements/invidam.go.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Intuition
2+
빈도수 계산, 정렬을 활용하면 가능하다고 생각했다. (깔끔하진 않아 해결될지는 의문이었다.)
3+
# Approach
4+
1. 빈도 수를 저장한다.
5+
2. 원소들을 빈도수(내림차순)대로 정렬한다.
6+
3. 정렬된 원소 중 앞에서부터 k개를 반환한다.
7+
# Complexity
8+
- Time complexity: $$O(nlog(n))$$
9+
- 배열의 길이 n에 대하여, 정렬비용으로 소모된다.
10+
11+
- Space complexity: $$O(n+k)$$
12+
- 배열의 길이 n과 원소의 범위 k에 대하여, 빈도수 저장을 위해 선언하는 비용 `k`와 정렬된 원소를 저장하는 비용 `n`이 소모된다.
13+
14+
# Code
15+
```go
16+
type NumAndFreq struct {
17+
Num int
18+
Freq int
19+
}
20+
21+
func topKFrequent(nums []int, k int) []int {
22+
freq := make(map[int]int, 20000)
23+
24+
for _, num := range nums {
25+
freq[num]++
26+
}
27+
28+
numAndFreqs := make([]NumAndFreq, 0, len(freq))
29+
for n, f := range freq {
30+
numAndFreqs = append(numAndFreqs, NumAndFreq{Num: n, Freq: f})
31+
}
32+
33+
sort.Slice(numAndFreqs, func(i, j int) bool {
34+
return numAndFreqs[i].Freq > numAndFreqs[j].Freq
35+
})
36+
37+
numsSortedByFreqDesc := make([]int, 0, len(nums))
38+
for _, e := range numAndFreqs {
39+
numsSortedByFreqDesc = append(numsSortedByFreqDesc, e.Num)
40+
}
41+
42+
return numsSortedByFreqDesc[0:k]
43+
}
44+
45+
```
46+
47+
# 여담
48+
- 타 솔루션들을 보며 정렬을 하지 않고 빈도수별로 원소들을 모아놨다가 배열을 만드는 방법도 확인했다. 직관적이진 않다고 느꼈다.
49+
- 문제 해결 도중 `map`, `filter`와 같은 함수형 프로그래밍을 활용하면 좋겠다는 생각이 들어 golang에서도 이를 제공하나 찾아봤다. [링크1](https://stackoverflow.com/questions/71624828/is-there-a-way-to-map-an-array-of-objects-in-go)[링크2](https://github.com/golang/go/issues/45955)를 통해 다양한 논의가 있었으나, 여러 이유로 도입하지 않음을 알게되었다.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# TC : O(n)
2+
# SC : O(n)
3+
from collections import defaultdict
4+
5+
6+
class Solution:
7+
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
8+
# Initialize a list of empty lists to store numbers based on their frequencies
9+
freq = [[] for i in range(len(nums) + 1)]
10+
11+
# Dictionary to count the frequency of each number
12+
counter = defaultdict(int)
13+
14+
# Count the frequency of each number in nums
15+
for num in nums:
16+
counter[num] += 1
17+
18+
# Group numbers by their frequency
19+
for n, c in counter.items():
20+
freq[c].append(n)
21+
22+
# Result list to store the top k frequent elements
23+
res = []
24+
25+
# Iterate over the frequency list in reverse order to get the most frequent elements first
26+
for i in range(len(freq) - 1, 0, -1):
27+
for n in freq[i]:
28+
res.append(n)
29+
# Once we have k elements in the result, return it
30+
if len(res) == k:
31+
return res

0 commit comments

Comments
 (0)
Please sign in to comment.