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;
};