寻找正序数组中位数
正则表达式匹配
盛最多水的容器
电话号码的字母组合
螺旋矩阵
合并两个有序数组
二叉树的最大路径和
分发糖果
数组中第K个最大元素
超级回文数
最长公共子序列
acm模式
const rl = require("readline").createInterface({ input: process.stdin });var iter = rl[Symbol.asyncIterator]();const readline = async () => (await iter.next()).value;void async function () { // Write your code here while(line = await readline()){ let tokens = line.split(' '); let a = parseInt(tokens[0]); let b = parseInt(tokens[1]); console.log(a + b); }}()
-
寻找正序数组中位数
var findMedianSortedArrays = function(nums1, nums2) { if (nums1.length > nums2.length) { [nums1, nums2] = [nums2, nums1]; } const m = nums1.length; const n = nums2.length; let low = 0, high = m; while (low <= high) { const partitionX = Math.floor((low + high) / 2); const partitionY = Math.floor((m + n + 1) / 2) - partitionX; const maxX = (partitionX === 0) ? Number.MIN_SAFE_INTEGER : nums1[partitionX - 1]; const maxY = (partitionY === 0) ? Number.MIN_SAFE_INTEGER : nums2[partitionY - 1]; const minX = (partitionX === m) ? Number.MAX_SAFE_INTEGER : nums1[partitionX]; const minY = (partitionY === n) ? Number.MAX_SAFE_INTEGER : nums2[partitionY]; if (maxX <= minY && maxY <= minX) { if ((m + n) % 2 === 0) { return (Math.max(maxX, maxY) + Math.min(minX, minY)) / 2; } else { return Math.max(maxX, maxY); } } else if (maxX > minY) { high = partitionX - 1; } else { low = partitionX + 1; } } throw new Error("Input arrays are not sorted."); }; -
var isMatch = function(string, pattern) { if (!pattern) { return !string; } const hasFirstCharMatch = Boolean(string) && (pattern[0] === '.' || pattern[0] === string[0]); // track when the next character * is next in line in the pattern if (pattern[1] === '*') { return ( isMatch(string, pattern.slice(2)) || (hasFirstCharMatch && isMatch(string.slice(1), pattern)) ); } return hasFirstCharMatch ? isMatch(string.slice(1), pattern.slice(1)) : false; };
3. 盛最多水的容器
/**
* @param {number[]} height
* @return {number}
*/
var maxArea = function(height) {
const n = height.length
let max = 0
let i = 0
let j = n - 1
while(i < j) {
const tmp = (j - i) * Math.min(height[i], height[j])
if(tmp > max) {
max = tmp
}
if(height[i] < height[j]) {
i++
} else {
j--
}
}
return max
};
4. 电话号码的字母组合
/**
* @param {string} digits
* @return {string[]}
*/
var letterCombinations = function (digits) {
if (!digits) {
return [];
}
const phoneMap = {
'2': 'abc',
'3': 'def',
'4': 'ghi',
'5': 'jkl',
'6': 'mno',
'7': 'pqrs',
'8': 'tuv',
'9': 'wxyz'
};
let combinations = [''];
for (const digit of digits) {
const newCombinations = [];
for (const combination of combinations) {
for (const letter of phoneMap[digit]) {
newCombinations.push(combination + letter);
}
}
combinations = newCombinations;
}
return combinations;
};
5. 字母异位词分组
/**
* @param {string[]} strs
* @return {string[][]}
*/
var groupAnagrams = function(strs) {
const mp = new Map();
const ans = [];
for (const str of strs) {
const sortedStr = str.split('').sort().join('');
if (mp.has(sortedStr)) {
ans[mp.get(sortedStr)].push(str);
} else {
mp.set(sortedStr, ans.length);
ans.push([str]);
}
}
return ans;
};
6. 最大子数组和
/**
* @param {number[]} nums
* @return {number}
*/
var maxSubArray = function(nums) {
// Initialize the max sum...
let maxSum = nums[0];
// Traverse all the element through the loop...
for (let i = 1; i < nums.length; i++) {
// nums[i] represents the largest sum of all subarrays ending with index i...
// then its value should be the larger one between nums[i]...
// nums[i-1] + nums[i] (largest sum plus current number with using prefix)...
// calculate nums[0], nums[1]…, nums[n] while comparing each one with current largest sum...
nums[i] = Math.max(0, nums[i - 1]) + nums[i];
// if nums[i] > maxSum then maxSum = nums[i]...
if (nums[i] > maxSum)
maxSum = nums[i];
}
return maxSum; // return the contiguous subarray which has the largest sum...
};
7. 螺旋矩阵
/**
* @param {number[][]} matrix
* @return {number[]}
*/
var spiralOrder = function(matrix) {
const res = [];
while (matrix.length) {
// 取第一行
const first = matrix.shift();
res.push(...first);
// 取每行的最后一个元素
for (let i = 0; i < matrix.length; i++) {
let val = matrix[i].pop();
if (val !== undefined) res.push(val);
}
// 反转矩阵,准备下一轮遍历
matrix.reverse();
// 将矩阵每一行反转,以保持正确的遍历方向
for (let i = 0; i < matrix.length; i++) {
matrix[i].reverse();
}
}
return res;
};
8. 合并两个有序数组
/**
* @param {number[]} nums1
* @param {number} m
* @param {number[]} nums2
* @param {number} n
* @return {void} Do not return anything, modify nums1 in-place instead.
*/
var merge = function(nums1, m, nums2, n) {
let i = 0
let j = 0
let res = []
while(i<m && j<n){
if(nums1[i] <= nums2[j]) {
res.push(nums1[i])
i++
} else {
res.push(nums2[j])
j++
}
}
while(i<m) {
res.push(nums1[i])
i++
}
while(j<n) {
res.push(nums2[j])
j++
}
nums1.splice(0, m+n, ...res)
};
二叉树的最大路径和
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
const maxPathSum = (root) => {
let max = -Infinity;
const findSums = (node) => {
// Base case / hit a null
if (!node) return 0;
let left = findSums(node.left),
right = findSums(node.right),
allSum = left + right + node.val,
leftNodeSum = left + node.val,
rightNodeSum = right + node.val;
// Max is all possible combinations
max = Math.max(max, node.val, allSum, leftNodeSum, rightNodeSum);
// Return the MAX path, which can be node.val, left + node.val, or right + node.val
return Math.max(leftNodeSum, rightNodeSum, node.val);
};
findSums(root);
return max;
};
分发糖果
/**
* @param {number[]} ratings
* @return {number}
*/
var candy = function(ratings) {
if (ratings.length === 0) {
return 0;
}
let ret = 1, up = 0, down = 0, peak = 0;
for (let i = 0; i < ratings.length - 1; i++) {
const prev = ratings[i], curr = ratings[i + 1];
if (prev < curr) {
up++;
down = 0;
peak = up;
ret += 1 + up;
} else if (prev === curr) {
up = 0;
down = 0;
peak = 0;
ret += 1;
} else {
up = 0;
down++;
ret += 1 + down;
if (peak >= down) {
ret--;
}
}
}
return ret;
};
数组中第K个最大元素
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
var findKthLargest = function(nums, k) {
return quickSelect(nums, 0, nums.length - 1, nums.length - k);
};
function quickSelect(nums, left, right, k) {
while (left <= right) {
const pivotIndex = partition(nums, left, right);
if (k === pivotIndex) {
return nums[k];
} else if (k < pivotIndex) {
right = pivotIndex - 1;
} else {
left = pivotIndex + 1;
}
}
return -1; // 应该不会到达这里
}
function partition(nums, left, right) {
const pivotIndex = medianOfThree(nums, left, right);
const pivot = nums[pivotIndex];
swap(nums, pivotIndex, right); // 把枢轴移到末尾
let i = left;
for (let j = left; j < right; j++) {
if (nums[j] < pivot) {
swap(nums, i++, j);
}
}
swap(nums, i, right); // 把枢轴移到最终位置
return i;
}
function medianOfThree(nums, left, right) {
const mid = left + ((right - left) >> 1);
if (nums[left] > nums[mid]) swap(nums, left, mid);
if (nums[left] > nums[right]) swap(nums, left, right);
if (nums[mid] > nums[right]) swap(nums, mid, right);
return mid;
}
function swap(nums, i, j) {
[nums[i], nums[j]] = [nums[j], nums[i]];
}
超级回文数
/**
* @param {string} left
* @param {string} right
* @return {number}
*/
var superpalindromesInRange = function(left, right) {
let ans = 9 >= left && 9 <= right ? 1 : 0
const isPal = str => {
for (let i = 0, j = str.length - 1; i < j; i++, j--)
if (str.charAt(i) !== str.charAt(j)) return false
return true
}
for (let dig = 1; dig < 10; dig++) {
let isOdd = dig % 2 && dig !== 1,
innerLen = (dig >> 1) - 1, innerLim = Math.max(1, 2 ** innerLen),
midPos = dig >> 1, midLim = isOdd ? 3 : 1
for (let edge = 1; edge < 3; edge++) {
let pal = new Uint8Array(dig)
pal[0] = edge, pal[dig-1] = edge
if (edge === 2) innerLim = 1, midLim = Math.min(midLim, 2)
for (let inner = 0; inner < innerLim; inner++) {
if (inner > 0) {
let innerStr = inner.toString(2).padStart(innerLen, '0')
for (let i = 0; i < innerLen; i++)
pal[1+i] = innerStr[i], pal[dig-2-i] = innerStr[i]
}
for (let mid = 0; mid < midLim; mid++) {
if (isOdd) pal[midPos] = mid
let palin = ~~pal.join(""),
square = BigInt(palin) * BigInt(palin)
if (square > right) return ans
if (square >= left && isPal(square.toString())) ans++
}
}
}
}
return ans
};
最长公共子序列
/**
* @param {string} text1
* @param {string} text2
* @return {number}
*/
var longestCommonSubsequence = function(text1, text2) {
// Lengths of the input strings
const length1 = text1.length;
const length2 = text2.length;
// Create a 2D array to store the lengths of longest common subsequences
// for all subproblems, initialized with zero
const dp = new Array(length1 + 1).fill(0).map(() => new Array(length2 + 1).fill(0));
// Build the dp array from the bottom up
for (let i = 1; i <= length1; ++i) {
for (let j = 1; j <= length2; ++j) {
// If characters match, take diagonal value and add 1
if (text1.charAt(i - 1) === text2.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1] + 1;
}
// If characters do not match, take the maximum value from
// the left (dp[i][j-1]) or above (dp[i-1][j])
else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
// The bottom-right cell contains the length of the longest
// common subsequence of text1 and text2
return dp[length1][length2];
};