Skip to content

Commit 5920e71

Browse files
authored
refactor: js - two pointers (neetcode-gh#455)
1 parent 69cf2c4 commit 5920e71

File tree

5 files changed

+150
-184
lines changed

5 files changed

+150
-184
lines changed
Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,35 @@
11
/**
2+
* https://leetcode.com/problems/container-with-most-water/
3+
* Time O(N) | Space(1)
24
* @param {number[]} height
35
* @return {number}
46
*/
5-
var maxArea = function (height) {
6-
let max = 0;
7-
let i = 0;
8-
let j = height.length - 1;
9-
10-
while (i < j) {
11-
const curr = (j - i) * Math.min(height[i], height[j]);
12-
max = Math.max(curr, max);
13-
if (height[i] > height[j]) {
14-
j--;
15-
} else {
16-
i++;
17-
}
7+
var maxArea = function(height) {
8+
let [ left, right, max ] = [ 0, (height.length - 1), 0 ];
9+
10+
while (left < right) {
11+
const [ leftHeight, rightHeight ] = getHeights(height, left, right);
12+
const area = getArea(height, left, right);
13+
14+
max = Math.max(max, area);
15+
16+
const isRightGreater = leftHeight <= rightHeight;
17+
if (isRightGreater) left++;
18+
19+
const isRightLess = rightHeight < leftHeight;
20+
if (isRightLess) right--;
1821
}
22+
1923
return max;
2024
};
25+
26+
const getHeights = (height, left, right) => [ height[left], height[right] ];
27+
28+
const getArea = (height, left, right) => {
29+
const [ leftHeight, rightHeight ] = getHeights(height, left, right);
30+
const _height = Math.min(leftHeight, rightHeight);
31+
const width = right - left;
32+
33+
return _height * width;
34+
};
35+

javascript/125-Valid-Palindrome.js

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,36 @@
1-
const ALPHA_NUM = /^[a-zA-Z0-9]$/;
2-
3-
function isPalindrome(s) {
4-
let l = 0;
5-
let r = s.length - 1;
6-
7-
while (l < r) {
8-
while (l < r && !ALPHA_NUM.test(s[l])) {
9-
l++;
10-
}
11-
while (l < r && !ALPHA_NUM.test(s[r])) {
12-
r--;
13-
}
14-
15-
if (s[l].toLowerCase() !== s[r].toLowerCase()) {
16-
return false;
17-
}
18-
19-
l++;
20-
r--;
1+
/**
2+
* https://leetcode.com/problems/valid-palindrome/
3+
* Time O(N) | Space O(1)
4+
* @param {string} s
5+
* @return {boolean}
6+
*/
7+
var isPalindrome = function(s) {
8+
if (!s.length) return true;
9+
10+
s = s.toLowerCase();
11+
12+
return isValid(s);
13+
};
14+
15+
const isValid = (s) => {
16+
let [ left, right ] = [ 0, (s.length - 1) ];
17+
18+
while (left < right) {
19+
while ((left < right) && isNonAlphaNumeric(s[left])) left++;
20+
while ((left < right) && isNonAlphaNumeric(s[right])) right--;
21+
22+
const isSame = s[left] === s[right];
23+
if (!isSame) return false;
24+
25+
left++; right--;
2126
}
2227

2328
return true;
2429
}
30+
31+
const isNonAlphaNumeric = (char) => {
32+
const isNonAlpha = char < 'a' || 'z' < char; // a(97) - z(122)
33+
const isNonNumeric = char < '0' || '9' < char; // 0(48) - 9(57)
34+
35+
return isNonAlpha && isNonNumeric;
36+
};

javascript/15-3Sum.js

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,48 @@
11
/**
2+
* https://leetcode.com/problems/3sum/
3+
* Time O(N ^ 2) | Space O(N)
24
* @param {number[]} nums
35
* @return {number[][]}
46
*/
5-
var threeSum = function (nums) {
6-
let res = [];
7-
let left = 0;
8-
let right = nums.length - 1;
9-
nums.sort((a, b) => {
10-
return a - b;
11-
});
12-
13-
for (let i = 0; i < nums.length - 1; i++) {
14-
if (nums[i] > 0) return res;
15-
if (nums[i] === nums[i - 1]) continue;
16-
17-
left = i + 1;
18-
right = nums.length - 1;
19-
let temp = 0;
20-
21-
while (left < right) {
22-
temp = nums[left] + nums[right] + nums[i];
23-
if (temp === 0) {
24-
res.push([nums[i], nums[left], nums[right]]);
25-
left++;
26-
right--;
27-
28-
while (nums[left] == nums[left - 1]) {
29-
left++;
30-
}
31-
32-
while (nums[right] == nums[right + 1]) {
33-
right--;
34-
}
35-
} else if (temp > 0) {
36-
right--;
37-
} else if (temp < 0) {
38-
left++;
39-
}
40-
}
7+
var threeSum = function(nums, sums = []) {
8+
nums.sort((a, b) => a - b);
9+
10+
for (let first = 0; first < nums.length - 2; first++) {
11+
if (isPrevDuplicate(nums, first)) continue;
12+
13+
const [ target, left, right ] = [ (-nums[first]), (first + 1), (nums.length - 1) ];
14+
15+
search(nums, target, left, right, sums);
4116
}
42-
return res;
17+
18+
return sums;
4319
};
20+
21+
const isPrevDuplicate = (nums, index) => nums[index - 1] === nums[index];
22+
23+
const isNextDuplicate = (nums, index) => nums[index] === nums[index + 1];
24+
25+
const search = (nums, target, left, right, sums) => {
26+
while (left < right) {
27+
const [ leftVal, rightVal ] = [ nums[left], nums[right] ];
28+
const sum = leftVal + rightVal;
29+
30+
const isTarget = sum === target;
31+
if (isTarget) {
32+
sums.push([ -target, leftVal, rightVal ]);
33+
left++;
34+
right--;
35+
36+
while (left < right && isPrevDuplicate(nums, left)) left++;
37+
while (left < right && isNextDuplicate(nums, right)) right--;
38+
39+
continue;
40+
}
41+
42+
const isTargetGreater = sum < target;
43+
if (isTargetGreater) left++;
44+
45+
const isTargetLess = target < sum;
46+
if (isTargetLess) right--;
47+
}
48+
};

javascript/167-Two-Sum-II.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
/**
2+
* https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/
3+
* Time O(N) | Space O(1)
24
* @param {number[]} numbers
35
* @param {number} target
46
* @return {number[]}
57
*/
6-
var twoSum = function (numbers, target) {
7-
let start = 0;
8-
let end = numbers.length - 1;
9-
while (start < end) {
10-
let currSum = numbers[start] + numbers[end];
11-
if (currSum > target) end--;
12-
else if (currSum < target) start++;
13-
else return [start + 1, end + 1];
8+
var twoSum = function(numbers, target) {
9+
let [ left, right ] = [ 0, (numbers.length - 1) ];
10+
11+
while (left < right) {
12+
const sum = numbers[left] + numbers[right];
13+
14+
const isTarget = sum === target;
15+
if (isTarget) return [ (left + 1), (right + 1) ];
16+
17+
const isTargetGreater = sum < target;
18+
if (isTargetGreater) left++;
19+
20+
const isTargetLess = target < sum;
21+
if (isTargetLess) right--;
1422
}
15-
return [];
23+
24+
return [ -1, -1 ];
1625
};
Lines changed: 30 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1,119 +1,44 @@
1-
//////////////////////////////////////////////////////////////////////////////
2-
// Time: O(n) Space: O(1) One iteration.
3-
//////////////////////////////////////////////////////////////////////////////
4-
51
/**
6-
* @param {!Array<number>} heights
2+
* https://leetcode.com/problems/trapping-rain-water/
3+
* Time O(N) | Space O(1)
4+
* @param {number[]} height
75
* @return {number}
86
*/
9-
function trap(heights) {
10-
let l = 0;
11-
let r = heights.length - 1;
12-
let lMax = 0;
13-
let rMax = 0;
14-
let total = 0;
15-
16-
while (l < r) {
17-
if (heights[l] < heights[r]) {
18-
if (heights[l] >= lMax) {
19-
lMax = heights[l];
20-
} else {
21-
total += lMax - heights[l];
22-
}
23-
++l;
24-
} else {
25-
if (heights[r] >= rMax) {
26-
rMax = heights[r];
27-
} else {
28-
total += rMax - heights[r];
29-
}
30-
--r;
7+
var trap = function(height) {
8+
let [ left, right ] = [ 0, (height.length - 1) ];
9+
let [ maxLeft, maxRight, area ] = [ 0, 0, 0 ];
10+
11+
while (left < right) {
12+
const [ leftHeight, rightHeight ] = getHeights(height, left, right);
13+
const [ leftWindow, rightWindow ] = getWindows(height, left, maxLeft, right, maxRight);
14+
15+
const isRightGreater = leftHeight <= rightHeight;
16+
if (isRightGreater) {
17+
if (hasNewMax(maxLeft, leftHeight)) maxLeft = leftHeight;
18+
else area += leftWindow;
19+
20+
left++;
3121
}
32-
}
3322

34-
return total;
35-
}
23+
const isRightLess = rightHeight < leftHeight;
24+
if (isRightLess) {
25+
if (hasNewMax(maxRight, rightHeight)) maxRight = rightHeight;
26+
else area += rightWindow;
3627

37-
//////////////////////////////////////////////////////////////////////////////
38-
// Time: O(n) Space: O(n) Two iterations (one main loop and one stack).
39-
//////////////////////////////////////////////////////////////////////////////
40-
41-
/**
42-
* @param {!Array<number>} heights
43-
* @return {number}
44-
*/
45-
function trap(heights) {
46-
const stack = [];
47-
let total = 0;
48-
49-
for (let i = 0; i < heights.length; ++i) {
50-
while (stack.length && heights[i] > heights[top(stack)]) {
51-
const j = stack.pop();
52-
53-
if (!stack.length) {
54-
break;
55-
}
56-
57-
const k = top(stack);
58-
const spread = i - k - 1;
59-
const height = Math.min(heights[i], heights[k]) - heights[j];
60-
total += spread * height;
28+
right--;
6129
}
62-
63-
stack.push(i);
6430
}
6531

66-
return total;
67-
}
68-
69-
/**
70-
* @param {!Array<*>} stack
71-
* @return {*}
72-
*/
73-
function top(stack) {
74-
return stack[stack.length - 1];
75-
}
32+
return area;
33+
};
7634

77-
//////////////////////////////////////////////////////////////////////////////
78-
// Time: O(n) Space: O(n) Three iterations (two main loop and one stack).
79-
//////////////////////////////////////////////////////////////////////////////
35+
const hasNewMax = (max, height) => max < height;
8036

81-
/**
82-
* @param {!Array<number>} heights
83-
* @return {number}
84-
*/
85-
function trap(heights) {
86-
let valley = [];
87-
let barrier = 0;
88-
let trapped = 0;
37+
const getHeights = (height, left, right) => [ height[left], height[right] ];
8938

90-
for (const height of heights) {
91-
if (height >= barrier) {
92-
while (valley.length) {
93-
trapped += barrier - valley.pop();
94-
}
95-
barrier = height;
96-
} else {
97-
valley.push(height);
98-
}
99-
}
100-
101-
valley.reverse();
102-
valley.push(barrier);
103-
heights = valley;
104-
valley = [];
105-
barrier = 0;
106-
107-
for (const height of heights) {
108-
if (height >= barrier) {
109-
while (valley.length) {
110-
trapped += barrier - valley.pop();
111-
}
112-
barrier = height;
113-
} else {
114-
valley.push(height);
115-
}
116-
}
39+
const getWindows = (height, left, maxLeft, right, maxRight) => {
40+
const [ leftHeight, rightHeight ] = getHeights(height, left, right);
41+
const [ leftWindow, rightWindow ] = [ (maxLeft - leftHeight), (maxRight - rightHeight) ];
11742

118-
return trapped;
43+
return [ leftWindow, rightWindow ];
11944
}

0 commit comments

Comments
 (0)