// 从上到下打印二叉树 I 每一层都是从左到右
var levelOrder = function (root) {
if (!root) return [];
var queue = [root];
var res = [];
while (queue.length) {
var len = queue.length;
for (var i = 0; i < len; i++) {
var node = queue.shift();
if (node) {
res.push(node.val);
if (node.left) queue.push(node.left);
if (node.right) queue.push(node.right);
}
}
}
return res;
};
// 从上到下打印二叉树 II 每一层都是从左到右,但是每一层打印到一行
var levelOrder = (root) => {
if (!root) return [];
const res = [];
const queue = [root];
while (queue.length) {
let len = queue.length;
res.push([]);
for (var i = 0; i < len; i++) {
var node = queue.shift();
if (node) {
res[res.length - 1].push(node.val);
node.left && queue.push(node.left);
node.right && queue.push(node.right);
}
}
}
return res;
};
// 从上到下打印二叉树 III 奇数层从左到右,偶数层从右到左,但是每一层打印到一行
var levelOrder = (root) => {
if (!root) return [];
const res = [];
const queue = [root];
var n = 2;
while (queue.length) {
let len = queue.length;
res.push([]);
for (var i = 0; i < len; i++) {
var node = queue.shift();
if (node) {
res[res.length - 1].push(node.val);
node.left && queue.push(node.left);
node.right && queue.push(node.right);
}
}
if (n % 2) {
res[res.length - 1].reverse();
}
n++;
}
return res;
};
// 对称的二叉树
var isSymmetric = (root) => {
if (!root) return true;
const queue = [root.left, root.right];
while (queue.length) {
const len = queue.length;
for (let i = 0; i < len; i += 2) {
const left = queue.shift();
const right = queue.shift();
if ((left && !right) || (!left && right)) return false;
if (left && right) {
if (left.val !== right.val) return false;
queue.push(left.left, right.right, left.right, right.left);
}
}
}
return true;
};
//二叉树的最近公共祖先
var lowestCommonAncestor = (root, p, q) => {
if (!root) return null;
if (root === p || root === q) return root;
const left = lowestCommonAncestor(root.left, p, q);
const right = lowestCommonAncestor(root.right, p, q);
if (left && right) return root;
if (left) return left;
if (right) return right;
};
// 二叉搜索树的最近公共祖先
var lowestCommonAncestor = (root, p, q) => {
if (!root) return null;
if (root.val > p.val && root.val > q.val) {
return lowestCommonAncestor(root.left, p, q);
}
if (root.val < p.val && root.val < q.val) {
return lowestCommonAncestor(root.right, p, q);
}
return root;
};
// 二叉树的深度
const maxDepth = (root) => {
if (!root) return 0;
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
};
// 平衡二叉树
// 输入一棵二叉树的根节点,判断该树是不是平衡二叉树。
// 如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
const isBalanced = (root) => {
if (!root) return true;
return (
Math.abs(getH(root.left) - getH(root.right)) <= 1 &&
isBalanced(root.left) &&
isBalanced(root.right)
);
function getH(root) {
if (!root) return 0;
return Math.max(getH(root.left), getH(root.right)) + 1;
}
};
// 二叉搜索树的第k大节点
const kthLargest = (root, k) => {
const res = [];
f(root);
return res[k - 1];
function f(node) {
if (!node) return;
f(node.right);
res.push(node.val);
f(node.left);
}
};
// 已知二叉树,输出该二叉树的镜像
var mirrorTree = function (root) {
return f(root);
function f(node) {
if (!node) return node;
var mid = node.right;
node.right = f(node.left);
node.left = f(mid);
return node;
}
};
// 输入两棵二叉树A和B,判断B是不是A的子结构,(约定空树不是任意一个树的子结构)
var isSubStructure = function (A, B) {
if (!A || !B) return false;
return (
isSame(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B)
);
function isSame(A, B) {
if (!B) return true; // A和B都是一个叶节点,他们的左右子节点做比较,会走这里判断
if (!A) return false; // B存在,A不存在
if (A.val !== B.val) return false;
return isSame(A.left, B.left) && isSame(A.right, B.right);
}
};
// 在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字
var missingNumber = function (nums) {
if (nums.length === 1 && nums[0] === 1) {
return 0;
}
if (nums.length === 1 && nums[0] === 0) {
return 1;
}
var len = nums.length;
for (var i = 0; i < len; i++) {
if (nums[i + 1] && nums[i + 1] - nums[i] > 1) {
return nums[i] + 1;
}
}
if (nums[0] == 0) {
return nums[len - 1] + 1;
} else {
return 0;
}
};
// 构建乘积数组
var constructArr = function (a) {
let n = a.length;
if (!n) return [];
let result = new Array(n).fill(1);
let rightAccu = 1;
for (let i = 1; i < n; i++) {
result[i] = result[i - 1] * a[i - 1];
}
for (let i = n - 2; i >= 0; i--) {
// 构建右边乘积,以a = [1, 2, 3, 4, 5]举例,这里的temp会分别等于5、20、60、120
rightAccu *= a[i + 1];
// 乘以左边的乘积
result[i] *= rightAccu;
}
return result;
};
// constructArr([1, 2, 3, 4, 5])
// 入栈 出栈
var validateStackSequences = (pushed, popped) => {
let stack = [];
var index = 0;
for (var i = 0; i < pushed.length; i++) {
stack.push(pushed[i]);
while (
popped[index] !== undefined &&
popped[index] === stack[stack.length - 1]
) {
stack.pop();
index++;
}
}
return !stack.length;
};
// 滚动窗口
var maxSlidingWindow = (nums, k) => {
const len = nums.length;
if (!len) return [];
const q = [];
for (let i = 0; i < k; i++) {
while (q.length && nums[i] >= nums[q[q.length - 1]]) {
q.pop();
}
q.push(i);
}
const res = [nums[q[0]]];
for (let i = k; i < len; i++) {
while (q.length && nums[i] >= nums[q[q.length - 1]]) {
q.pop();
}
q.push(i);
while (q[0] <= i - k) {
q.shift();
}
res.push(nums[q[0]]);
}
return res;
};
// maxSlidingWindow([1, 3, -1, -3, 5, 3, 6, 7], 3)
// 求两个数之和,不可用加法
var add = function (a, b) {
let sum, carry;
do {
sum = a ^ b;
carry = (a & b) << 1;
a = sum;
b = carry;
} while (b != 0);
return a;
};
// 和为target的两个数字,nums是递增数组
const twoSum = (nums, target) => {
let [left, right] = [0, nums.length - 1];
while (left < right) {
sum = nums[left] + nums[right];
if (sum > target) {
right--;
} else if (sum < target) {
left++;
} else {
return [nums[left], nums[right]];
}
}
};
// 三个数字之和为0,[-1,0,1,2,-1,-1,-4],输出各种情况[[-1,-1,2],[-1,0,1]]
var threeSum = function (nums) {
nums.sort((a, b) => a - b);
var len = nums.length;
var res = [];
for (var i = 0; i < len; i++) {
if (nums[i] == nums[i - 1]) continue;
var left = i + 1;
var right = len - 1;
var value = nums[i];
while (left < right) {
if (value + nums[left] + nums[right] == 0) {
res.push([value, nums[left], nums[right]]);
while (nums[left] == nums[++left]);
while (nums[right] == nums[--right]);
} else if (value + nums[left] + nums[right] < 0) {
left++;
} else {
right--;
}
}
}
return res;
};
// 求连续子数组和为target,输出各种情况的个数
var subarraySum = function (nums, k) {
var len = nums.length;
var n = 0;
for (var i = 0; i < len; i++) {
if (nums[i] === k) {
n++;
}
var sum = nums[i];
for (var j = i + 1; j < len; j++) {
sum += nums[j];
if (sum === k) {
n++;
}
}
}
return n;
};
// 求最短连续子数组和大于target,返回它的长度
// 7 [2, 3, 1, 4, 2, 3] 得出长度为3 而不是2
var minSubArrayLen = function (target, nums) {
var len = nums.length + 1;
var i = 0;
var sum = 0;
for (var j = 0; j < nums.length; j++) {
sum += nums[j];
while (sum >= target) {
if (j - i + 1 < len) {
len = j - i + 1;
}
sum -= nums[i++];
}
}
return len > nums.length ? 0 : len;
};
// 求连续子数组乘积小于target,所有可能情况的个数
var numSubarrayProductLessThanK = function (nums, t) {
var len = nums.length;
var n = 0;
for (var i = 0; i < len; i++) {
if (nums[i] >= t) continue;
n++;
var sum = nums[i];
for (var j = i + 1; j < len; j++) {
sum *= nums[j];
if (sum >= t) break;
n++;
}
}
return n;
};
// 求最长连续子数组,返回它的长度,满足0和1的个数相等
var findMaxLength = function (nums) {
var len = nums.length;
var map = new Map();
var key = 0;
map.set(key, -1);
var maxlen = 0;
for (var i = 0; i < len; i++) {
if (nums[i] == 1) {
key++;
} else {
key--;
}
if (map.has(key)) {
var k = map.get(key);
maxlen = Math.max(maxlen, i - k);
} else {
map.set(key, i);
}
}
return maxlen;
};
// 找寻中心轴元素下标,左右两边子数组的和相等
var pivotIndex = function (nums) {
var add = nums.reduce(function (acc, item) {
return (acc += item);
}, 0);
var sum = 0;
for (var i = 0; i < nums.length; i++) {
if (add == nums[i] + 2 * sum) return i;
sum += nums[i];
}
return -1;
};
// 二进制加法
var addBinary = function (a, b) {
var count = 0;
var sum = "";
var i, j;
var temp;
for (i = a.length - 1, j = b.length - 1; i > -1 && j > -1; i--, j--) {
temp = count + parseInt(a[i]) + parseInt(b[j]);
sum += temp > 1 ? String(temp - 2) : String(temp);
count = temp > 1 ? 1 : 0;
}
var k = i > j ? i : j;
var arr = i > j ? a : b;
while (k > -1) {
temp = count + parseInt(arr[k]);
sum += temp > 1 ? String(temp - 2) : String(temp);
count = temp > 1 ? 1 : 0;
k--;
}
if (count === 1) {
sum += "1";
}
return sum.split("").reverse().join("");
};
// 整数除法
var divide = function (a, b) {
const {
abs, pow } = Math;
const MAX = pow(2, 31) - 1;
var MIN = -pow(2, 31);
if (a == MIN && b == -1) return MAX;
if (a == MIN && b == 1) return MIN;
const sign = (a > 0) ^ (b > 0);
a = abs(a);
b = abs(b);
let n = 0;
while (a >= b) {
a -= b;
n++;
}
return sign ? -n : n;
};
// 整数转二进制后,含有1的个数
function f(i) {
var j = 0;
while (i > 0) {
i = i & (i - 1);
j++;
}
return j;
}
// 股票最大利润
var maxProfit = function (prices) {
var min = prices[0];
var maxValue = 0;
for (var i = 1; i < prices.length; i++) {
if (prices[i] < min) {
min = prices[i];
} else {
maxValue = Math.max(maxValue, prices[i] - min);
}
}
return maxValue;
};
// 圆圈中最后剩下的数字
const lastRemaining = (n, m) => {
let res = 0;
for (let i = 2; i <= n; i++) {
res = (res + m) % i;
}
return res;
};
// 扑克牌中的顺子
const isStraight = (nums) => {
const set = new Set();
let [max, min] = [0, 14];
for (const num of nums) {
if (num === 0) continue;
max = Math.max(max, num);
min = Math.min(min, num);
if (set.has(num)) return false;
set.add(num);
}
return max - min < 5;
};
// 一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。
var singleNumbers = function (nums) {
var obj = {
};
var len = nums.length;
for (var i = 0; i < len; i++) {
if (obj[nums[i]] !== undefined) {
delete obj[nums[i]];
} else {
obj[nums[i]] = i;
}
}
return Object.keys(obj);
};
// 在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。
var singleNumber = function (nums) {
var obj = {
};
for (var i = 0; i < nums.length; i++) {
if (obj[nums[i]] === undefined) {
obj[nums[i]] = 1;
} else if (obj[nums[i]] === 1) {
obj[nums[i]]++;
} else {
delete obj[nums[i]];
}
}
return Object.keys(obj);
};
// 输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。
var findContinuousSequence = function (target) {
var mid = target >> 1;
var res = [];
for (var i = 1; i < mid; i++) {
var j = i;
var sum = i;
var arr = [];
while (sum < target) {
arr.push(j);
j++;
sum += j;
if (sum == target) {
arr.push(j);
res.push(arr);
continue;
}
}
}
if (target % 2 !== 0) {
res.push([mid, mid + 1]);
}
return res;
};
// 输入两个链表,找出它们的第一个公共节点。
const getIntersectionNode = (a, b) => {
let x = a,
y = b;
while (x !== y) {
if (x === null) {
x = b;
} else {
x = x.next;
}
if (y === null) {
y = a;
} else {
y = y.next;
}
}
return x;
};
// 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
// 方法一
const lengthOfLongestSubstring1 = (s) => {
const arr = [];
let max = 0;
const len = s.length;
for (let i = 0; i < len; i++) {
const index = arr.indexOf(s[i]);
if (index !== -1) {
arr.splice(0, index + 1);
}
arr.push(s[i]);
if (max < arr.length) max = arr.length;
}
return max;
};
// 方法二
var lengthOfLongestSubstring2 = function (s) {
var arr = s.split("");
var maxlen = 0;
for (var i = 0; i < arr.length; i++) {
var brr = [];
var j = i;
while (arr[j] && !brr.includes(arr[j])) {
brr.push(arr[j]);
j++;
}
maxlen = Math.max(maxlen, brr.length);
}
return maxlen;
};
// 礼物的最大价值
const maxValue = (dArr) => {
const [m, n] = [dArr.length, dArr[0].length];
const dp = new Array(m).fill(0).map(() => new Array(n).fill(0));
dp[0][0] = dArr[0][0];
// 补充第一列初始化
for (let i = 1; i < m; i++) {
dp[i][0] = dp[i - 1][0] + dArr[i][0];
}
// 补充第一行初始化
for (let j = 1; j < n; j++) {
dp[0][j] = dp[0][j - 1] + dArr[0][j];
}
// 遍历,完善dp数组
for (let i = 1; i < m; i++) {
for (let j = 1; j < n; j++) {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]) + dArr[i][j];
}
}
return dp[m - 1][n - 1];
};
// 顺时针打印二维数组
var spiralOrder = function (arr) {
if (!arr.length || !arr[0].length) return [];
let left = 0,
right = arr[0].length - 1,
top = 0,
bottom = arr.length - 1,
result = [];
while (true) {
for (let i = left; i <= right; i++) result.push(arr[top][i]);
if (++top > bottom) break;
for (let i = top; i <= bottom; i++) result.push(arr[i][right]);
if (--right < left) break;
for (let i = right; i >= left; i--) result.push(arr[bottom][i]);
if (--bottom < top) break;
for (let i = bottom; i >= top; i--) result.push(arr[i][left]);
if (++left > right) break;
}
return result;
};
// 把数组排成最小的数
var minNumber = function (nums) {
var len = nums.length;
for (var i = 0; i < len; i++) {
for (var j = i + 1; j < len; j++) {
swap(i, j, nums);
}
}
return nums.join("");
function swap(i, j, nums) {
var ij = Number(String(nums[i]) + String(nums[j]));
var ji = Number(String(nums[j]) + String(nums[i]));
if (ij > ji) {
var mid = nums[i];
nums[i] = nums[j];
nums[j] = mid;
}
}
};
// 连续子数组的最大和
// nums = [-2,1,-3,4,-1,2,1,-5,4]
var maxSubArray = (nums) => {
if (nums.length === 1) return nums[0];
let max = nums[0];
for (let i = 1; i < nums.length; i++) {
if (nums[i - 1] > 0) {
nums[i] += nums[i - 1];
}
max = max > nums[i] ? max : nums[i];
}
return max;
};
var maxSubArray = (nums) => {
let curSum = nums[0];
let maxSum = nums[0];
for (let i = 1; i < nums.length; i++) {
curSum = Math.max(nums[i], nums[i] + curSum);
maxSum = Math.max(curSum, maxSum);
}
return maxSum;
};
// [3,2,2,1] 3 输出[1,2,2]
var getLeastNumbers = function (arr, k) {
if (k == 0) return [];
for (var i = 0; i < arr.length; i++) {
for (var j = i; j < arr.length; j++) {
if (arr[i] > arr[j]) {
var mid = arr[i];
arr[i] = arr[j];
arr[j] = mid;
}
}
if (i + 1 == k) return arr.slice(0, k);
}
};
// 可能有重复的字符串,自由组合的种类
var permutation = function (s) {
var arr = s.split("");
var len = arr.length;
var res = [];
fn(0);
function swap(i, j, arr) {
if (i == j) return;
var mid = arr[i];
arr[i] = arr[j];
arr[j] = mid;
}
function fn(i) {
if (i == len - 1) return res.push(arr.join(""));
var set = new Set();
for (var j = i; j < len; j++) {
if (set.has(arr[j])) continue;
set.add(arr[j]);
swap(i, j, arr);
fn(i + 1);
swap(j, i, arr);
}
}
return res;
};
// 复制一个复杂的链表,random指向随机
// head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
function Node(val, next, random) {
this.val = val;
this.next = next;
this.random = random;
}
var copyRandomList = function (head) {
if (!head) return head;
var map = new Map();
var node = head;
while (node) {
map.set(node, new Node(node.val));
node = node.next;
}
node = head;
while (node) {
var item = map.get(node);
item.next = map.get(node.next) ? map.get(node.next) : null;
item.random = map.get(node.random) ? map.get(node.random) : null;
node = node.next;
}
return map.get(head);
};
// 反转每对括号间的子串
var reverseParentheses = function (s) {
var stock = [];
var arr = s.split("");
var len = arr.length;
for (var i = 0; i < len; i++) {
if (arr[i] == "(") {
stock.push(i);
}
if (arr[i] == ")") {
var index = stock[stock.length - 1];
var str = s
.slice(index, i + 1)
.split("")
.reverse()
.join("");
s = s.slice(0, index) + str + s.slice(i + 1);
stock.pop();
}
}
s = s.replace(/[\(\)]/g, "");
return s;
};
// s = "11111222223", k = 3
// 3465 = 346 + 5
// 13 + 5
// 135 返回135
var digitSum = function (s, k) {
return f(s, k);
function f(s, k) {
if (s.length <= k) return s;
var arr = [];
for (var i = 0; i < s.length; i += k) {
if (i > s.length) break;
arr.push(sum(s.slice(i, i + k)));
}
var str = arr.join("");
return f(str, k);
}
function sum(str) {
return str.split("").reduce(function (acc, item) {
acc = acc + Number(item);
return acc;
}, 0);
}
};
// 判断arr 是否是 二叉搜索数后续遍历
const verifyPostorder = (arr) => {
const len = arr.length;
if (len <= 1) return true;
const root = arr[len - 1];
let i = 0;
while (arr[i] < root) i++;
const res = arr.slice(i, len - 1).every((x) => x > root);
return res
? verifyPostorder(arr.slice(0, i)) && verifyPostorder(arr.slice(i, len - 1))
: false;
};
// 二维矩阵中
var exist = function (arr, str) {
if (!arr) return false;
var m = arr.length;
var n = arr[0].length;
for (var i = 0; i < m; i++) {
for (var j = 0; j < n; j++) {
if (dfs(i, j, 0)) return true;
}
}
function dfs(i, j, x) {
if (i < 0 || j < 0 || i >= m || j >= n || arr[i][j] != str[x]) return false;
if (x == str.length - 1) return true;
var mid = arr[i][j];
arr[i][j] = "";
var res =
dfs(i + 1, j, x + 1) ||
dfs(i, j + 1, x + 1) ||
dfs(i - 1, j, x + 1) ||
dfs(i, j - 1, x + 1);
arr[i][j] = mid;
return res;
}
return false;
};
// 二维矩阵,求子矩阵的各项和
var NumMatrix = function (matrix) {
var [m, n] = [matrix.length, matrix[0].length];
var dp = Array.from({
length: m }, () => new Array(n + 1).fill(0));
for (var i = 0; i < m; i++) {
for (var j = 0; j < n; j++) {
dp[i][j + 1] = dp[i][j] + matrix[i][j];
}
}
this.dp = dp;
};
NumMatrix.prototype.sumRegion = function (row1, col1, row2, col2) {
var dp = this.dp;
var sum = 0;
for (var i = row1; i <= row2; i++) {
sum += dp[i][col2 + 1] - dp[i][col1];
}
return sum;
};
// 重建二叉树,arr前序遍历 brr为中序遍历,且数组没有重复的值
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
var buildTree = function (arr, brr) {
return f(arr, brr);
function f(arr, brr) {
if (!arr.length) return null;
var value = arr[0];
var root = new TreeNode(value);
if (arr.length === 1) return root;
var index = brr.indexOf(value);
var leftTree2 = brr.slice(0, index);
var rightTree2 = brr.slice(index + 1);
var leftTree1 = arr.slice(1, index + 1);
var rightTree1 = arr.slice(index + 1);
root.left = f(leftTree1, leftTree2);
root.right = f(rightTree1, rightTree2);
return root;
}
};
// 两个递增链表合并
const mergeTwoLists = (l1, l2) => {
const res = new ListNode(0);
let p = res;
while (l1 && l2) {
if (l1.val < l2.val) {
p.next = l1;
l1 = l1.next;
} else {
p.next = l2;
l2 = l2.next;
}
p = p.next;
}
p.next = l1 ? l1 : l2;
return res.next;
};
// 链表反转
var reverseList = function (head) {
// 1 -> 2 -> 3 -> 4 -> 5 -> NULL
// NULL <- 1 <- 2 <- 3 <- 4 <- 5
var pre = null;
var cur = head;
while (cur) {
var next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
};
// 两个递增数组合并
function f(arr, brr) {
var res = [];
while (arr.length && brr.length) {
if (arr[0] > brr[0]) {
res.push(brr[0]);
brr.shift();
} else {
res.push(arr[0]);
arr.shift();
}
}
return arr.length ? res.concat(arr) : res.concat(brr);
}
// 链表中倒数第k个节点
var getKthFromEnd = function (head, k) {
// 1->2->3->4->5, 和 k = 2
var quick = head;
while (k--) {
quick = quick.next;
}
var node = head;
while (quick) {
node = node.next;
quick = quick.next;
}
return node;
};
// 实现 pow(x, n)
var myPow = function (x, n) {
if (n == 0) return 1;
if (n < 0) return 1 / myPow(x, -n);
if (n % 2 == 1) return x * myPow(x, n - 1);
return myPow(x * x, n / 2);
};
// 机器人的运动范围
var movingCount = function (m, n, k) {
var arr = Array.from({
length: m }, () => Array(n).fill(false));
return dfs(0, 0, arr);
function dfs(i, j, arr) {
if (i >= m || j >= n) return 0;
if (k < sum(i, j)) return 0;
if (arr[i][j]) return 0;
arr[i][j] = true;
return 1 + dfs(i + 1, j, arr) + dfs(i, j + 1, arr);
}
function sum(i, j) {
var sum = 0;
while (i) {
sum += i % 10;
i = (i / 10) >> 0;
}
while (j) {
sum += j % 10;
j = (j / 10) >> 0;
}
return sum;
}
};
// 从尾到头打印链表 ,用数组返回
var reversePrint = function (head) {
var node = head;
var res = [];
while (node) {
res.push(node.val);
node = node.next;
}
res.reverse();
return res;
};
// 前n个丑数,1是丑数,其余的都是 2,3,5乘的
/**
输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。
*/
var nthUglyNumber = function (n) {
var nums = new Array(n).fill(0);
nums[0] = 1;
var index2 = 0;
var index3 = 0;
var index5 = 0;
/**
1, 2, 3, 4, 5, 6, 8, 9, 10, 12
0 0 0
1 0 0
1 1 0
2 1 0
2 1 1
3 2 1
*/
for (var i = 1; i < n; i++) {
nums[i] = Math.min(nums[index2] * 2, nums[index3] * 3, nums[index5] * 5);
if (nums[i] == nums[index2] * 2) {
index2++;
}
if (nums[i] == nums[index3] * 3) {
index3++;
}
if (nums[i] == nums[index5] * 5) {
index5++;
}
}
return nums[n - 1];
};
// ["a","ab","abc","d","cd","bcd","abcd"] 两个串没有重叠部分,最长乘积
var maxProduct = function (words) {
var max = 0;
for (var i = 0; i < words.length; i++) {
for (var j = i + 1; j < words.length; j++) {
var value = f(words[i], words[j]);
max = Math.max(max, value);
}
}
return max;
function f(s1, s2) {
var set = Array.from([...s2]).join("");
var reg = new RegExp(`[${
set}]`);
var flag = reg.test(s1);
if (flag) return 0;
return s1.length * s2.length;
}
};
// 检测两个字符串是否相同的字符
function f(s1, s2) {
var str1;
for (var i = 0; i < s1.length; i++) {
str1 |= 1 << (s1[i].charCodeAt() - "a".charCodeAt());
}
var str2;
for (var i = 0; i < s2.length; i++) {
str2 |= 1 << (s2[i].charCodeAt() - "a".charCodeAt());
}
return !!(str1 & str2);
}
// s1 = 'ab' s1的变位词为 "ab"或者"ba"
// s2 = "cbad" s2的子串中"ba"刚好是s1的变位词之一,找到一个就返回true
var checkInclusion = function (s1, s2) {
var m = s1.length;
var n = s2.length;
if (m > n) return false;
var arr = new Array(26).fill(0);
var brr = new Array(26).fill(0);
for (var i = 0; i < m; i++) {
arr[s1[i].charCodeAt() - "a".charCodeAt()]++;
brr[s2[i].charCodeAt() - "a".charCodeAt()]++;
}
if (arr.toString() === brr.toString()) return true;
for (var i = m; i < n; i++) {
brr[s2[i].charCodeAt() - "a".charCodeAt()]++;
brr[s2[i - m].charCodeAt() - "a".charCodeAt()]--;
if (arr.toString() === brr.toString()) return true;
}
return false;
};
// 找出 字符串s2中存在的所有 s1的变位词,并返回起始下标
var findAnagrams = function (s2, s1) {
var m = s1.length;
var n = s2.length;
if (m > n) return [];
var arr = new Array(26).fill(0);
var brr = new Array(26).fill(0);
var res = [];
for (var i = 0; i < m; i++) {
arr[s1[i].charCodeAt(0) - "a".charCodeAt(0)]++;
brr[s2[i].charCodeAt(0) - "a".charCodeAt(0)]++;
}
if (arr.toString() == brr.toString()) res.push(0);
for (var j = m; j < n; j++) {
brr[s2[j].charCodeAt(0) - "a".charCodeAt(0)]++;
brr[s2[j - m].charCodeAt(0) - "a".charCodeAt(0)]--;
if (arr.toString() == brr.toString()) res.push(j - m + 1);
}
return res;
};
// 有效的回文
// "A man, a plan, a canal: Panama"
// "amanaplanacanalpanama"
var isPalindrome = function (s) {
var len = s.length;
var arr = [];
for (var i = 0; i < len; i++) {
if (/[A-Za-z0-9]/.test(s[i])) {
arr.push(s[i].toLowerCase());
}
}
return arr.join("") === arr.reverse().join("");
};
// 字符串删除一个字符后,是否形成回文字符串
var validPalindrome = function (s) {
var left = 0;
var right = s.length - 1;
while (left < right) {
if (s[left] == s[right]) {
++left;
--right;
} else {
return (
checkPalindrome(s, left, right - 1) ||
checkPalindrome(s, left + 1, right)
);
}
}
return true;
function checkPalindrome(s, i, j) {
while (i < j) {
if (s[i] != s[j]) return false;
i++;
j--;
}
return true;
}
};
// 字符串的子串,是回文字符串的个数
var countSubstrings = function (s) {
var len = s.length;
var count = 0;
for (var i = 0; i < len; i++) {
for (var j = i + 1; j < len + 1; j++) {
if (checkPalindrome(s.slice(i, j))) {
count++;
}
}
}
return count;
function checkPalindrome(s) {
var i = 0;
var j = s.length - 1;
while (i < j) {
if (s[i] != s[j]) return false;
i++;
j--;
}
return true;
}
};
// 链表中如果有环,则输出环的入口节点
var detectCycle = function (head) {
var node = head;
var map = new Map();
while (node) {
map.set(node, true);
node = node.next;
if (map.has(node)) return node;
}
return null;
};
// 两个链表,返回第一个重合的地方
var getIntersectionNode1 = function (headA, headB) {
var set = new Set();
while (headA || headB) {
if (headA) {
if (set.has(headA)) {
return headA;
} else {
set.add(headA);
headA = headA.next;
}
}
if (headB) {
if (set.has(headB)) {
return headB;
} else {
set.add(headB);
headB = headB.next;
}
}
}
return null;
};
var getIntersectionNode2 = function (headA, headB) {
var node1 = headA;
var node2 = headB;
var n = 0;
while (node1 !== node2) {
node1 = node1.next;
node2 = node2.next;
if (node1 == null) {
node1 = headB;
n++;
if (n == 2) return null;
}
if (node2 == null) {
node2 = headA;
}
}
return node1;
};
// 链表反转
var reverseList = function (head) {
var pre = null;
var cur = head;
while (cur) {
var next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
};
// 两链表,对应的数相加,生成新的链表
var addTwoNumbers = function (l1, l2) {
var arr1 = []; // [3,4,2,7]
var arr2 = []; //[4,6,5]
var p1 = l1;
var p2 = l2;
while (p1 || p2) {
if (p1) {
arr1.unshift(p1.val);
p1 = p1.next;
}
if (p2) {
arr2.unshift(p2.val);
p2 = p2.next;
}
}
var brr = [];
var car = 0; // 前一个数加的进位数 1|0
while (arr1.length || arr2.length) {
if (arr1.length && arr2.length) {
var sum = arr1.shift() + arr2.shift() + car;
} else if (arr1.length) {
var sum = arr1.shift() + car;
} else {
var sum = arr2.shift() + car;
}
brr.push(sum % 10);
car = sum >= 10 ? 1 : 0;
}
brr.reverse(); // [7,0,8,7] ==> [7,8,0,7]
if (car == 1) brr.unshift(1);
var head = new ListNode();
var node = head;
for (var val of brr) {
node = node.next = new ListNode(val);
}
return head.next;
};
刷leetcode力扣算法题目
猜你喜欢
转载自blog.csdn.net/formylovetm/article/details/126340991
今日推荐
周排行