1.分割平衡字符串
题目:
在一个「平衡字符串」中,'L' 和 'R' 字符的数量是相同的。
给出一个平衡字符串 s,请你将它分割成尽可能多的平衡字符串。
返回可以通过分割得到的平衡字符串的最大数量。
思路:用两个变量记录L和R的数量,相等的时候+1
/**
* @param {string} s
* @return {number}
*/
var balancedStringSplit = function(s) {
let vr = 0;
let vl = 0;
let c = 0;
for (const i of s) {
if (i == "L") {
vl++;
} else {
vr++;
}
if (vr && vr == vl) {
c++;
vr = 0;
vl = 0;
}
}
return c;
};
2.缀点成线
题目:
在一个 XY 坐标系中有一些点,我们用数组 coordinates 来分别记录它们的坐标,其中 coordinates[i] = [x, y] 表示横坐标为 x、纵坐标为 y 的点。
请你来判断,这些点是否在该坐标系中属于同一条直线上,是则返回 true,否则请返回 false。
思路:比较斜率即可,注意垂直的线段
/**
* @param {number[][]} coordinates
* @return {boolean}
*/
var checkStraightLine = function(coordinates) {
const l = coordinates.length;
if (l == 2) return true;
let v;
v =
(coordinates[1][1] - coordinates[0][1]) /
(coordinates[1][0] - coordinates[0][0]);
for (let i = 1; i < l - 1; i++) {
const temp =
(coordinates[i + 1][1] - coordinates[i][1]) /
(coordinates[i + 1][0] - coordinates[i][0]);
if (v == Infinity && coordinates[i + 1][0] - coordinates[i][0] === 0)
continue;
if (temp !== v) return false;
}
return true;
};
3.找出给定方程的正整数解
题目:
给出一个函数 f(x, y) 和一个目标结果 z,请你计算方程 f(x,y) == z 所有可能的正整数 数对 x 和 y。
给定函数是严格单调的,也就是说:
f(x, y) < f(x + 1, y)
f(x, y) < f(x, y + 1)
函数接口定义如下:
interface CustomFunction {
public:
// Returns positive integer f(x, y) for any given positive integer x and y.
int f(int x, int y);
};
如果你想自定义测试,你可以输入整数 function_id 和一个目标结果 z 作为输入,其中 function_id 表示一个隐藏函数列表中的一个函数编号,题目只会告诉你列表中的 2 个函数。
思路:枚举,从x=0,y=1000开始枚举,因为是单调递增的,所以如果大于解,y减一,反之x加一。(从x=1000,y=0开始枚举也一样)
/**
* // This is the CustomFunction's API interface.
* // You should not implement it, or speculate about its implementation
* function CustomFunction() {
* @param {integer, integer} x, y
* @return {integer}
* this.f = function(x, y) {
* ...
* };
* };
*/
/**
* @param {CustomFunction} customfunction
* @param {integer} z
* @return {integer[][]}
*/
var findSolution = function(customfunction, z) {
let res = [];
let x = 1;
let y = 1000;
while(x > 0 && x <= 1000 && y > 0 && y <= 1000) {
if (customfunction.f(x, y) === z) {
let ans = [x, y];
res.push(ans);
x++;
}
else if (customfunction.f(x, y) > z) {
y--;
}
else {
x++;
}
}
return res;
};
4.奇数值单元格的数目
题目:
给你一个 n 行 m 列的矩阵,最开始的时候,每个单元格中的值都是 0。
另有一个索引数组 indices,indices[i] = [ri, ci] 中的 ri 和 ci 分别表示指定的行和列(从 0 开始编号)。
你需要将每对 [ri, ci] 指定的行和列上的所有单元格的值加 1。
请你在执行完所有 indices 指定的增量操作后,返回矩阵中 「奇数值单元格」 的数目。
思路:记录每一行和每一列新增的数目,对应单元格的次数就是相加
/**
* @param {number} n
* @param {number} m
* @param {number[][]} indices
* @return {number}
*/
var oddCells = function(n, m, indices) {
const map1 = new Map();
const map2 = new Map();
for (const [row, column] of indices) {
map1.set(row, (map1.get(row) || 0) + 1);
map2.set(column, (map2.get(column) || 0) + 1);
}
let count = 0;
for (let i = 0; i < n; i++) {
for (let j = 0; j < m; j++) {
if (((map1.get(i) || 0) + (map2.get(j) || 0)) % 2) count++;
}
}
return count;
};
5.二维网格迁移
题目:
给你一个 m 行 n 列的二维网格 grid 和一个整数 k。你需要将 grid 迁移 k 次。
每次「迁移」操作将会引发下述活动:
位于 grid[i][j] 的元素将会移动到 grid[i][j + 1]。
位于 grid[i][n - 1] 的元素将会移动到 grid[i + 1][0]。
位于 grid[m - 1][n - 1] 的元素将会移动到 grid[0][0]。
请你返回 k 次迁移操作后最终得到的 二维网格。
思路:每一次迁移,就是将最后一列取出,最后一个元素放在开头,然后这一列插入到矩阵的第一列。第一种方法是依次迁移
/**
* @param {number[][]} grid
* @param {number} k
* @return {number[][]}
*/
var shiftGrid = function(grid, k) {
for (let i = 0; i < k; i++) {
const temp = grid.map((item) => item.pop());
temp.unshift(temp.pop());
grid.forEach((item) => {
item.unshift(temp.shift());
});
}
return grid;
};
第二种方法是计算迁移次数。对于m*n的矩阵,观察可知,每移动m*n次矩阵就重复依次,每移动m次,所有列都执行了一次操作:最后一个元素放在开头,。所以先计算k%(m*n),去掉重复的迁移,然后计算~~(k/m),每一列操作几次,再计算k%m,当前这一轮循环操作了几列
/**
* @param {number[][]} grid
* @param {number} k
* @return {number[][]}
*/
var shiftGrid = function(grid, k) {
const h = grid.length;
const w = grid[0].length;
k = k % (h * w);
const a = ~~(k / w);
const b = k % w;
grid.splice(0, 0, ...grid.splice(h - a, h));
for (let i = 0; i < b; i++) {
const temp = grid.map((item) => item.pop());
temp.unshift(temp.pop());
grid.forEach((item) => {
item.unshift(temp.shift());
});
}
return grid;
};