Skip to content

Commit d9d15d5

Browse files
committed
add 10 medium
1 parent 4b2fda1 commit d9d15d5

File tree

3 files changed

+378
-3
lines changed

3 files changed

+378
-3
lines changed

benchmarks/easy.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import * as easy from "../src/easy.ts";
22

33
Deno.bench("twoSum", () => {
4-
easy.twoSum([2, 7, 11, 15], 9)
4+
easy.twoSum([2, 7, 11, 15], 9);
55
});
66

77
Deno.bench("palindromeNumber", () => {
8-
easy.palindromeNumber(123321);
9-
});
8+
easy.palindromeNumber(123321);
9+
});

src/medium.ts

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
import { ListNode } from "./utils.ts";
2+
3+
/**
4+
* https://leetcode.com/problems/add-two-numbers/
5+
* @param l1
6+
* @param l2
7+
* @returns
8+
*/
9+
export function addTwoNumbers(
10+
l1: ListNode | null,
11+
l2: ListNode | null,
12+
): ListNode | null {
13+
const dummyHead = new ListNode(0);
14+
let curr = dummyHead;
15+
let carry = 0;
16+
while (l1 !== null || l2 !== null || carry !== 0) {
17+
const x = l1 !== null ? l1.val : 0;
18+
const y = l2 !== null ? l2.val : 0;
19+
const sum = carry + x + y;
20+
carry = Math.floor(sum / 10);
21+
curr.next = new ListNode(sum % 10);
22+
curr = curr.next;
23+
if (l1 !== null) l1 = l1.next;
24+
if (l2 !== null) l2 = l2.next;
25+
}
26+
return dummyHead.next;
27+
}
28+
29+
/**
30+
* https://leetcode.com/problems/longest-substring-without-repeating-characters/
31+
* @param s
32+
* @returns
33+
*/
34+
export function longestSubstringWithoutRepeatingCharacters(s: string): number {
35+
let length = 0;
36+
const characterMap = new Map();
37+
let leftIndex = 0;
38+
39+
for (let rightIndex = 0; rightIndex < s.length; rightIndex++) {
40+
const character = s[rightIndex];
41+
if (
42+
characterMap.has(character) && characterMap.get(character) >= leftIndex
43+
) {
44+
leftIndex = characterMap.get(character) + 1;
45+
}
46+
length = Math.max(length, rightIndex - leftIndex + 1);
47+
characterMap.set(character, rightIndex);
48+
}
49+
return length;
50+
}
51+
52+
/**
53+
* https://leetcode.com/problems/longest-palindromic-substring/
54+
* @param s
55+
* @returns
56+
*/
57+
export function longestPalindromicSubstring(s: string): string {
58+
function expandAroundCenter(left: number, right: number): string {
59+
while (left >= 0 && right < s.length && s[left] === s[right]) {
60+
left--;
61+
right++;
62+
}
63+
return s.substring(left + 1, right);
64+
}
65+
66+
let longest = "";
67+
68+
for (let i = 0; i < s.length; i++) {
69+
const odd = expandAroundCenter(i, i);
70+
const even = expandAroundCenter(i, i + 1);
71+
72+
if (odd.length > longest.length) {
73+
longest = odd;
74+
}
75+
76+
if (even.length > longest.length) {
77+
longest = even;
78+
}
79+
}
80+
81+
return longest;
82+
}
83+
84+
/**
85+
* https://leetcode.com/problems/zigzag-conversion/
86+
* @param s
87+
* @param numRows
88+
* @returns
89+
*/
90+
export function zigzagConversion(s: string, numRows: number): string {
91+
if (numRows === 1) return s;
92+
93+
const rows = new Array(numRows).fill("");
94+
95+
let currRow = -1;
96+
let direction = 1;
97+
98+
for (let i = 0; i < s.length; i++) {
99+
currRow += direction;
100+
rows[currRow] += s[i];
101+
102+
if (currRow == numRows - 1) direction = -1;
103+
else if (currRow == 0) direction = 1;
104+
}
105+
106+
return rows.join("");
107+
}
108+
109+
/**
110+
* https://leetcode.com/problems/reverse-integer/
111+
* @param x
112+
* @returns
113+
*/
114+
export function reverseInteger(x: number): number {
115+
let rev: number = 0;
116+
while (x !== 0) {
117+
const pop: number = x % 10;
118+
x = (x - pop) / 10;
119+
if (
120+
rev > Math.pow(2, 31) / 10 ||
121+
(rev === Math.pow(2, 31) / 10 && pop > 7)
122+
) {
123+
return 0;
124+
}
125+
if (
126+
rev < Math.pow(-2, 31) / 10 ||
127+
(rev === Math.pow(-2, 31) / 10 && pop < -8)
128+
) {
129+
return 0;
130+
}
131+
rev = rev * 10 + pop;
132+
}
133+
return rev;
134+
}
135+
136+
/**
137+
* https://leetcode.com/problems/string-to-integer-atoi/
138+
* @param s
139+
* @returns
140+
*/
141+
export function stringToIntegerAtoi(s: string): number {
142+
let i = 0;
143+
while (s[i] === " ") i++;
144+
const sign = (s[i] === "+" || s[i] === "-") && s[i++] === "-" ? -1 : 1;
145+
let n = 0;
146+
while (47 < s.charCodeAt(i) && s.charCodeAt(i) < 58) n = n * 10 + +s[i++];
147+
return Math.min(2 ** 31 - 1, Math.max(-(2 ** 31), sign * n));
148+
}
149+
150+
/**
151+
* https://leetcode.com/problems/container-with-most-water/
152+
* @param height
153+
* @returns
154+
*/
155+
export function containerWithMostWater(height: number[]): number {
156+
let low = 0;
157+
let high = height.length - 1;
158+
let ans = 0;
159+
160+
while (low <= high) {
161+
const length = Math.min(height[low], height[high]);
162+
163+
const breadth = high - low;
164+
const area = length * breadth;
165+
166+
ans = Math.max(ans, area);
167+
168+
if (height[low] < height[high]) low++;
169+
else high--;
170+
}
171+
return ans;
172+
}
173+
174+
/**
175+
* https://leetcode.com/problems/integer-to-roman/
176+
* @param num
177+
* @returns
178+
*/
179+
export function integerToRoman(num: number): string {
180+
const rNums: Record<string, number> = {
181+
M: 1000,
182+
CM: 900,
183+
D: 500,
184+
CD: 400,
185+
C: 100,
186+
XC: 90,
187+
L: 50,
188+
XL: 40,
189+
X: 10,
190+
IX: 9,
191+
V: 5,
192+
IV: 4,
193+
I: 1,
194+
};
195+
let result = "";
196+
for (const rN in rNums) {
197+
const count = num / rNums[rN];
198+
if (count > 0) {
199+
result += rN.repeat(count);
200+
num = num % rNums[rN];
201+
}
202+
}
203+
return result;
204+
}
205+
206+
/**
207+
* https://leetcode.com/problems/3sum/
208+
* @param nums
209+
* @returns
210+
*/
211+
export function threeSum(nums: number[]): number[][] {
212+
nums.sort((a, b) => a - b);
213+
const result: number[][] = [];
214+
215+
for (let i = 0; i < nums.length - 2; i++) {
216+
if (i > 0 && nums[i] === nums[i - 1]) continue;
217+
218+
let j = i + 1;
219+
let k = nums.length - 1;
220+
221+
while (j < k) {
222+
const sum = nums[i] + nums[j] + nums[k];
223+
224+
if (sum === 0) {
225+
result.push([nums[i], nums[j], nums[k]]);
226+
while (j < k && nums[j] === nums[j + 1]) j++;
227+
while (j < k && nums[k] === nums[k - 1]) k--;
228+
j++;
229+
k--;
230+
} else if (sum < 0) {
231+
j++;
232+
} else {
233+
k--;
234+
}
235+
}
236+
}
237+
238+
return result;
239+
}
240+
241+
/**
242+
* https://leetcode.com/problems/3sum-closest/
243+
* @param nums
244+
* @param target
245+
* @returns
246+
*/
247+
export function threeSumClosest(nums: number[], target: number): number {
248+
const n = nums.length;
249+
let ans = 0;
250+
let diff = Number.MAX_SAFE_INTEGER;
251+
252+
nums.sort((a, b) => a - b);
253+
254+
for (let i = 0; i < n; i++) {
255+
let j = i + 1;
256+
let k = n - 1;
257+
258+
while (j < k) {
259+
const sum = nums[i] + nums[j] + nums[k];
260+
const tmp = Math.abs(target - sum);
261+
if (tmp < diff) {
262+
ans = sum;
263+
diff = tmp;
264+
}
265+
if (sum > target) k--;
266+
else j++;
267+
}
268+
}
269+
return ans;
270+
}

tests/test_medium.ts

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { assertEquals } from "@std/assert";
2+
import * as medium from "../src/medium.ts";
3+
import { ListNode } from "../src/utils.ts";
4+
5+
Deno.test(function addTwoNumbersTest() {
6+
assertEquals(
7+
medium.addTwoNumbers(
8+
new ListNode(2, new ListNode(4, new ListNode(3))),
9+
new ListNode(5, new ListNode(6, new ListNode(4))),
10+
),
11+
new ListNode(7, new ListNode(0, new ListNode(8))),
12+
);
13+
assertEquals(
14+
medium.addTwoNumbers(new ListNode(), new ListNode()),
15+
new ListNode(),
16+
);
17+
assertEquals(
18+
medium.addTwoNumbers(
19+
new ListNode(
20+
9,
21+
new ListNode(
22+
9,
23+
new ListNode(
24+
9,
25+
new ListNode(9, new ListNode(9, new ListNode(9, new ListNode(9)))),
26+
),
27+
),
28+
),
29+
new ListNode(9, new ListNode(9, new ListNode(9, new ListNode(9)))),
30+
),
31+
new ListNode(
32+
8,
33+
new ListNode(
34+
9,
35+
new ListNode(
36+
9,
37+
new ListNode(
38+
9,
39+
new ListNode(0, new ListNode(0, new ListNode(0, new ListNode(1)))),
40+
),
41+
),
42+
),
43+
),
44+
);
45+
});
46+
47+
Deno.test(function longestSubstringWithoutRepeatingCharactersTest() {
48+
assertEquals(
49+
medium.longestSubstringWithoutRepeatingCharacters("abcabcbb"),
50+
3,
51+
);
52+
assertEquals(medium.longestSubstringWithoutRepeatingCharacters("bbbbb"), 1);
53+
assertEquals(medium.longestSubstringWithoutRepeatingCharacters("pwwkew"), 3);
54+
});
55+
56+
Deno.test(function longestPalindromicSubstringTest() {
57+
assertEquals(medium.longestPalindromicSubstring("babad"), "bab");
58+
assertEquals(medium.longestPalindromicSubstring("cbbd"), "bb");
59+
});
60+
61+
Deno.test(function zigzagConversionTest() {
62+
assertEquals(medium.zigzagConversion("PAYPALISHIRING", 3), "PAHNAPLSIIGYIR");
63+
assertEquals(medium.zigzagConversion("PAYPALISHIRING", 4), "PINALSIGYAHRPI");
64+
assertEquals(medium.zigzagConversion("A", 1), "A");
65+
});
66+
67+
Deno.test(function reverseIntegerTest() {
68+
assertEquals(medium.reverseInteger(123), 321);
69+
assertEquals(medium.reverseInteger(-123), -321);
70+
assertEquals(medium.reverseInteger(120), 21);
71+
});
72+
73+
Deno.test(function stringToIntegerAtoiTest() {
74+
assertEquals(medium.stringToIntegerAtoi("42"), 42);
75+
assertEquals(medium.stringToIntegerAtoi("-042"), -42);
76+
assertEquals(medium.stringToIntegerAtoi("1337c0d3"), 1337);
77+
assertEquals(medium.stringToIntegerAtoi("0-1"), 0);
78+
assertEquals(medium.stringToIntegerAtoi("words and 987"), 0);
79+
});
80+
81+
Deno.test(function containerWithMostWaterTest() {
82+
assertEquals(medium.containerWithMostWater([1, 8, 6, 2, 5, 4, 8, 3, 7]), 49);
83+
assertEquals(medium.containerWithMostWater([1, 1]), 1);
84+
});
85+
86+
Deno.test(function integerToRomanTest() {
87+
assertEquals(medium.integerToRoman(3749), "MMMDCCXLIX");
88+
assertEquals(medium.integerToRoman(58), "LVIII");
89+
assertEquals(medium.integerToRoman(1994), "MCMXCIV");
90+
});
91+
92+
Deno.test(function threeSumTest() {
93+
assertEquals(medium.threeSum([-1, 0, 1, 2, -1, -4]), [[-1, -1, 2], [
94+
-1,
95+
0,
96+
1,
97+
]]);
98+
assertEquals(medium.threeSum([0, 1, 1]), []);
99+
assertEquals(medium.threeSum([0, 0, 0]), [[0, 0, 0]]);
100+
});
101+
102+
Deno.test(function threeSumClosestTest() {
103+
assertEquals(medium.threeSumClosest([-1, 2, 1, -4], 1), 2);
104+
assertEquals(medium.threeSumClosest([0, 0, 0], 1), 0);
105+
});

0 commit comments

Comments
 (0)