Skip to content

Commit cf3291d

Browse files
authored
Merge pull request #101 from sounmind/main
Evan: Week 5
2 parents de9b51a + f634742 commit cf3291d

File tree

5 files changed

+224
-0
lines changed

5 files changed

+224
-0
lines changed

3sum/evan.js

+60
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+
*/

encode-and-decode-strings/evan.js

+58
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"]

longest-consecutive-sequence/evan.js

+38
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+
*/

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

+33
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+
*/

top-k-frequent-elements/evan.js

+35
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+
*/

0 commit comments

Comments
 (0)