1.最长和谐子序列
题目:
和谐数组是指一个数组里元素的最大值和最小值之间的差别正好是1。
现在,给定一个整数数组,你需要在所有可能的子序列中找到最长的和谐子序列的长度。
思路:遍历一遍数组,记录所有的数及出现的次数。然后比较 p[i]+p[i+1],更新最大值。遇到没有记录的数就作为-Infinity
/**
* @param {number[]} nums
* @return {number}
*/
var findLHS = function(nums) {
const map = new Map();
let res = 0;
for (const i of nums) {
map.set(i, (map.get(i) || 0) + 1);
}
for (const i of map.keys()) {
res = Math.max((map.get(i)||0) + ( map.get(i + 1)||-Infinity), res);
}
return res;
};
2.范围求和
题目:
给定一个初始元素全部为 0,大小为 m*n 的矩阵 M 以及在 M 上的一系列更新操作。
操作用二维数组表示,其中的每个操作用一个含有两个正整数 a 和 b 的数组表示,含义是将所有符合 0 <= i < a 以及 0 <= j < b 的元素 M[i][j] 的值都增加 1。
在执行给定的一系列操作后,你需要返回矩阵中含有最大整数的元素个数。
思路:因为是0-m和0-n,所以累加次数最多的肯定是0-m的最小值以及0-n的最小值、
/**
* @param {number} m
* @param {number} n
* @param {number[][]} ops
* @return {number}
*/
var maxCount = function(m, n, ops) {
let mina = m;
let minb = n;
for (const [a, b] of ops) {
mina = Math.min(mina, a);
minb = Math.min(minb, b);
}
return mina * minb;
};
3.两个列表的最小索引总和
题目:
假设Andy和Doris想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示。
你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅。 如果答案不止一个,则输出所有答案并且不考虑顺序。 你可以假设总是存在一个答案。
思路:先记录第一个数组出现过的字符和对应的下标,遍历第二个数组,遇到在第一个数组中出现过的,就比较两个下标之和和记录的最小下标和;如果当前值更小,清空然后记录当前的下标和,相等就加入,更大就跳过
/**
* @param {string[]} list1
* @param {string[]} list2
* @return {string[]}
*/
var findRestaurant = function(list1, list2) {
let min = Infinity;
const map = new Map();
for (let i = 0, l1 = list1.length; i < l1; i++) {
map.set(list1[i], i);
}
return list2.reduce((res, item, index) => {
if (map.has(item)) {
if (map.get(item) + index < min) {
min = map.get(item) + index;
res.splice(0, Infinity, item);
} else if (map.get(item) + index == min) {
res.push(item);
}
}
return res;
}, []);
};
4.种花问题
题目:
假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花),和一个数 n 。能否在不打破种植规则的情况下种入 n 朵花?能则返回True,不能则返回False。
思路:遍历数组,如果某个位置的数值是0,前一个位置及后一个位置也是0,则这个位置可以种花,此时下标多自增1。遍历完或者n等于0的时候返回结果
/**
* @param {number[]} flowerbed
* @param {number} n
* @return {boolean}
*/
var canPlaceFlowers = function(flowerbed, n) {
const l = flowerbed.length;
for (let i = 0; i < l; i++) {
if (!n) return true;
if (!flowerbed[i - 1]&& !flowerbed[i] && !flowerbed[i + 1]) {
n--;
i ++
}
}
return !n;
};
5.根据二叉树创建字符串
题目:
你需要采用前序遍历的方式,将一个二叉树转换成一个由括号和整数组成的字符串。
空节点则用一对空括号 "()" 表示。而且你需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。
示例 1:
输入: 二叉树: [1,2,3,4]
1
/ \
2 3
/
4
输出: "1(2(4))(3)"
解释: 原本将是“1(2(4)())(3())”,
在你省略所有不必要的空括号对之后,
它将是“1(2(4))(3)”。
示例 2:
输入: 二叉树: [1,2,3,null,4]
1
/ \
2 3
\
4
输出: "1(2()(4))(3)"
解释: 和第一个示例相似,
除了我们不能省略第一个对括号来中断输入和输出之间的一对一映射关系。
思路:关键是理解题意。每个括号包裹一颗子树,如果某个节点左节点有值右节点没值,右节点可以跳过;如果左节点没值右节点有值,左节点要作为一个空括号加入;如果左右节点都没值,则跳过两个子节点
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} t
* @return {string}
*/
var tree2str = function(t) {
let res = "";
const search = (root) => {
if (!root) {
return;
}
res += root.val;
if (!root.left && !root.right) return;
if (root.left) {
res += "(";
search(root.left);
res += ")";
if (root.right) {
res += "(";
search(root.right);
res += ")";
}
} else {
if (root.right) {
res += "()";
}
res += "(";
search(root.right);
res += ")";
}
};
search(t);
return res;
};