1.距离顺序排列矩阵单元格
题目:
给出 R 行 C 列的矩阵,其中的单元格的整数坐标为 (r, c),满足 0 <= r < R 且 0 <= c < C。
另外,我们在该矩阵中给出了一个坐标为 (r0, c0) 的单元格。
返回矩阵中的所有单元格的坐标,并按到 (r0, c0) 的距离从最小到最大的顺序排,其中,两单元格(r1, c1) 和 (r2, c2) 之间的距离是曼哈顿距离,|r1 - r2| + |c1 - c2|。(你可以按任何满足此条件的顺序返回答案。)
思路:先计算出每个矩阵的坐标,然后将矩阵转换为一维的数组,对数组进行排序
/*** @param {number} R* @param {number} C* @param {number} r0* @param {number} c0* @return {number[][]}*/
var allCellsDistOrder = function(R, C, r0, c0) {let res = new Array(R).fill("").map(() => new Array(C));for (let i = 0; i < R; i++) {for (let j = 0; j < C; j++) {res[i][j] = [i, j];}}res = res.flat();return res.sort((a, b) =>Math.abs(a[0] - r0) +Math.abs(a[1] - c0) -Math.abs(b[0] - r0) -Math.abs(b[1] - c0));
};
2.移动石子直到连续
题目:
三枚石子放置在数轴上,位置分别为 a,b,c。
每一回合,我们假设这三枚石子当前分别位于位置 x, y, z 且 x < y < z。从位置 x 或者是位置 z 拿起一枚石子,并将该石子移动到某一整数位置 k 处,其中 x < k < z 且 k != y。
当你无法进行任何移动时,即,这些石子的位置连续时,游戏结束。
要使游戏结束,你可以执行的最小和最大移动次数分别是多少? 以长度为 2 的数组形式返回答案:answer = [minimum_moves, maximum_moves]
思路:计算左侧和右侧最多可移动的次数。大就是左+右
/*** @param {number} a* @param {number} b* @param {number} c* @return {number[]}*/
var numMovesStones = function(a, b, c) {const res = [a, b, c].sort((a, b) => a - b);const left = res[1] - res[0] - 1;const right = res[2] - res[1] - 1;let min = 0;let max = left + right;if (left || right) {if (left > 1 && right > 1) {min = 2;} else {min = 1;}}return [min, max];
};
3.有效的回旋镖
题目:
回旋镖定义为一组三个点,这些点各不相同且不在一条直线上。
给出平面上三个点组成的列表,判断这些点是否可以构成回旋镖。
思路:计算两个点的斜率,斜率不同,就不在一个直线上
也可以计算三条边的长度,能组成三角形,就不在一条直线上
/*** @param {number[][]} points* @return {boolean}*/
var isBoomerang = function(points) {let dx1=points[0][0];let dx2=points[1][0];let dx3=points[2][0];let dy1=points[0][1];let dy2=points[1][1];let dy3=points[2][1];let ax1=dx1-dx2;let ay1=dy1-dy2;let ax2=dx1-dx3;let ay2=dy1-dy3;let k1=ay1/ax1;let k2=ay2/ax2;return k1!==k2&&!isNaN(k1)&&!isNaN(k2);};
4.不邻接植花
题目:
有 N 个花园,按从 1 到 N 标记。在每个花园中,你打算种下四种花之一。
paths[i] = [x, y] 描述了花园 x 到花园 y 的双向路径。
另外,没有花园有 3 条以上的路径可以进入或者离开。
你需要为每个花园选择一种花,使得通过路径相连的任何两个花园中的花的种类互不相同。
以数组形式返回选择的方案作为答案 answer,其中 answer[i] 为在第 (i+1) 个花园中种植的花的种类。花的种类用 1, 2, 3, 4 表示。保证存在答案。
思路:用map记录每个花园的相邻花园,然后从前往后遍历花园,保证花园的颜色和它相邻的花园已有的颜色不同即可
/*** @param {number} N* @param {number[][]} paths* @return {number[]}*/
const getColor = (nei) => {for (let i = 1; i <= 4; i++) {if (!nei.includes(i)) return i;}
};
var gardenNoAdj = function (N, paths) {const map = new Map();for (const [a, b] of paths) {if (map.get(a)) {map.get(a).push(b);} else {map.set(a, [b]);}if (map.get(b)) {map.get(b).push(a);} else {map.set(b, [a]);}}const res = new Array(N);for (let i = 0; i < N; i++) {res[i] = getColor((map.get(i + 1)||[]).map((i) => res[i - 1]));}return res;
};
5.最后一块石头的重量
题目:
有一堆石头,每块石头的重量都是正整数。
每一回合,从中选出两块 最重的 石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:
如果 x == y,那么两块石头都会被完全粉碎;
如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。
最后,最多只会剩下一块石头。返回此石头的重量。如果没有石头剩下,就返回 0。
思路:和之前一题,有效的成对括号类似,用栈存储石头
/*** @param {number[]} stones* @return {number}*/
var lastStoneWeight = function(stones) {stones.sort((a, b) => a - b);while (stones.length > 1) {const x = stones.pop();const y = stones.pop();if (x == y) continue;const index = stones.findIndex((i) => i >= x - y);stones.splice(index < 0 ? stones.length : index, 0, x - y);}return stones[0] || 0;
};