1.森林中的兔子
题目:
森林中,每个兔子都有颜色。其中一些兔子(可能是全部)告诉你还有多少其他的兔子和自己有相同的颜色。我们将这些回答放在 answers 数组里。
返回森林中兔子的最少数量。
思路:原则上是,有同样数量其余颜色的兔子尽可能用同一种颜色,所以对于answer[i],用map记录之前出现过的answer的数量。如果之前出现过的数量等于当前的同颜色兔子数量,说明这种颜色已经被用完了,重置该数量对应的值为0;如果是第一次出现,则加上answer[i]+1(加一是因为要加上自己)
时间复杂度O(n) 空间复杂度O(n)
/**
* @param {number[]} answers
* @return {number}
*/
var numRabbits = function(answers) {
const map = new Map();
let c = 0;
for (const n of answers) {
const v = map.get(n) || 0;
if (!v) {
c += n + 1;
}
map.set(n, v === n ? 0 : v + 1);
}
return c;
};
2.字母大小写全排列
题目:给定一个字符串S
,通过将字符串S
中的每个字母转变大小写,我们可以获得一个新的字符串。返回所有可能得到的字符串集合。
思路:排列组合的一种方式。可以递归深度遍历也可以用栈广度遍历。遍历字符串,遇到字母,则新增两个分支,分别是当前字母的大写和小写,并拼接之前的结果,作为下一次的拼接值。
时间复杂度O(2^N),空间复杂度O(2^N) N是字母的数量
/**
* @param {string} S
* @return {string[]}
*/
var letterCasePermutation = function(S) {
const res = [];
const l = S.length;
const findIndex = (pre) => {
let index = l;
for (let i = pre + 1; i < l; i++) {
if (S[i].charCodeAt() > 60) {
index = i;
break;
}
}
return index;
};
const index = findIndex(-1);
if (index === l) return [S];
const stack = [
{
index,
left: S.slice(0, index),
},
];
while (stack.length) {
const item = stack.shift();
const index = findIndex(item.index);
const v1 = `${item.left}${S[item.index].toLowerCase()}${S.slice(
item.index + 1,
index
)}`;
const v2 = `${item.left}${S[item.index].toUpperCase()}${S.slice(
item.index + 1,
index
)}`;
if (index === l) {
res.push(v1, v2);
} else {
stack.push({ index, left: v1 }, { index, left: v2 });
}
}
return res;
};
3.判断二分图
题目:
给定一个无向图graph,当这个图为二分图时返回true。
如果我们能将一个图的节点集合分割成两个独立的子集A和B,并使图中的每一条边的两个节点一个来自A集合,一个来自B集合,我们就将这个图称为二分图。
graph将会以邻接表方式给出,graph[i]表示图中与节点i相连的所有节点。每个节点都是一个在0到graph.length-1之间的整数。这图中没有自环和平行边: graph[i] 中不存在i,并且graph[i]中没有重复的值。
思路:深度递归处理。对于所有的节点i,从i=0开始遍历,节点的初始状态是0,遍历节点时,将节点状态变为1,并遍历和它相连的节点,状态是-1.如果遇到已经之前已经修改过状态的节点,判断之前的状态和当前的状态是否相同。相同的话停止当前遍历,不同则说明不符合条件,状态变为2做标识并停止遍历。最后判断所有节点的状态值是否有为2的
时间复杂度O(n),空间复杂度O(n)
/**
* @param {number[][]} graph
* @return {boolean}
*/
var isBipartite = function(graph) {
const l = graph.length;
const list = new Array(l).fill(0);
const set = new Set();
const dfs = (i, v) => {
set.add(i);
if (list[i] !== 0 && list[i] !== v) {
list[i] = 2;
return;
} else if (list[i] === v) {
return;
}
list[i] = v;
graph[i].forEach((item) => {
dfs(item, -1 * v);
});
};
for (let i = 0; i < l; i++) {
if (set.has(i)) continue;
dfs(i, 1);
}
return !list.some((item) => item === 2);
};
4.K站中转内最便宜的航班
题目:
有 n 个城市通过 m 个航班连接。每个航班都从城市 u 开始,以价格 w 抵达 v。
现在给定所有的城市和航班,以及出发城市 src 和目的地 dst,你的任务是找到从 src 到 dst 最多经过 k 站中转的最便宜的价格。 如果没有这样的路线,则输出 -1。
思路:深度遍历,记录到达每个城市在第k次中转时的价格,同样的中转次数时取较小值
时间复杂度O(nk),空间复杂度O(nk)
/**
* @param {number} n
* @param {number[][]} flights
* @param {number} src
* @param {number} dst
* @param {number} K
* @return {number}
*/
var findCheapestPrice = function(n, flights, src, dst, K) {
const map = new Map();
for (const [start, end, v] of flights) {
if (!map.has(start)) {
map.set(start, new Map());
}
map.get(start).set(end, v);
}
const dp = new Array(n).fill("").map(() => new Array(K + 1).fill(Infinity));
const dfs = (start, pre, k) => {
if (k > K) return;
const srcs = map.get(start);
if(!srcs)return
for (const [end, v] of srcs.entries()) {
const cur = pre + v;
if (dp[end][k] <= cur) continue;
dp[end][k] = cur;
if (end === dst) continue;
dfs(end, cur, k + 1);
}
};
dfs(src, 0, 0);
const min = Math.min(...dp[dst]);
return min === Infinity ? -1 : min;
};
5.逃脱阻碍者
题目:
你在进行一个简化版的吃豆人游戏。你从 [0, 0] 点开始出发,你的目的地是 target = [xtarget, ytarget] 。地图上有一些阻碍者,以数组 ghosts 给出,第 i 个阻碍者从 ghosts[i] = [xi, yi] 出发。所有输入均为 整数坐标 。
每一回合,你和阻碍者们可以同时向东,西,南,北四个方向移动,每次可以移动到距离原位置 1 个单位 的新位置。当然,也可以选择 不动 。所有动作 同时 发生。
如果你可以在任何阻碍者抓住你 之前 到达目的地(阻碍者可以采取任意行动方式),则被视为逃脱成功。如果你和阻碍者同时到达了一个位置(包括目的地)都不算是逃脱成功。
只有在你有可能成功逃脱时,输出 true ;否则,输出 false 。
思路:反向思路:只要有阻碍者先到达终点,就不可能赢。,所以比较绝对距离即可
时间复杂度O(n) 空间复杂度O(n)
/**
* @param {number[][]} ghosts
* @param {number[]} target
* @return {boolean}
*/
var escapeGhosts = function(ghosts, target) {
const distance = ghosts.map(
(item) => Math.abs(item[0] - target[0]) + Math.abs(item[1] - target[1])
);
return distance.every(
(item) => item > Math.abs(target[0]) + Math.abs(target[1])
);
};