携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 16 天,点击查看活动详情
绘制直线
原题地址
已知一个由像素点组成的单色屏幕,每行均有 w 个像素点,所有像素点初始为 0,左上角位置为 (0,0)。
现将每行的像素点按照 「每 32 个像素点」 为一组存放在一个 int 中,再依次存入长度为 length 的一维数组中。
我们将在屏幕上绘制一条从点 (x1,y) 到点 (x2,y) 的直线(即像素点修改为 1),请返回绘制过后的数组。
注意:
- 用例保证屏幕宽度
w可被32整除(即一个int不会分布在两行上)
示例1:
输入:length = 1, w = 32, x1 = 30, x2 = 31, y = 0
输出:[3]
解释:在第 0 行的第 30 位到第 31 位画一条直线,屏幕二进制形式表示为 [00000000000000000000000000000011],因此返回 [3]
示例2:
输入:length = 3, w = 96, x1 = 0, x2 = 95, y = 0
输出:[-1, -1, -1]
解释:由于二进制 11111111111111111111111111111111 的 int 类型代表 -1,因此返回 [-1,-1,-1]
提示:
1 <= length <=1 <= w <= 3 *0 <= x1 <= x2 < w0 <= y <= 10
思路分析
- 首先分析题目,翻译成通俗易懂的文字来解释,一行有
w个像素点,即有w / 32个int,然后从(x1,y)到(x2,y)位置上的为1,其余位置均为0,然后以32个像素为一个单位计算其整数值,然后存储在长度为length的数组中,整体画布大小长为w,高为length / (w / 32)。 - 理解题目后,我们来解题,思路是将画布整体转换为字符串来解决;
- 第一步:先构建一个
length * 32且每个字符均为0的字符串; - 第二步:画线,将
(x1,y)到(x2,y)的位置替换成1,替换的长度为x2 - x1 + 1,替换的起始点为y * w + x1,终止点为y * w + x2 + 1; - 第三步:将字符串每
32位为一组,然后计算每组的十进制值; - 第四步:遇到正数,直接将二进制转换为十进制数即可;
- 第五步:遇到负数,即最高位为
1,先将二进制数减1取反后乘以-1即为十进制数; - 第六步:按照顺序转换完成后,将对应的结果存入
res中返回即可。
AC 代码
/**
* @param {number} length
* @param {number} w
* @param {number} x1
* @param {number} x2
* @param {number} y
* @return {number[]}
*/
var drawLine = function(length, w, x1, x2, y) {
let str = new Array(length * 32).fill(0).join("")
str = str.substring(0, y * w + x1) + "1".repeat(x2 - x1 + 1) + str.substring(y * w + x2 + 1)
let res = []
for (let i = 0; i < length; i++) {
let temp = str.substring(i * 32, (i + 1) * 32)
if (temp[0] === "1") {
temp = ~(parseInt(temp, 2) - 1)
temp *= -1
}else {
temp = parseInt(temp, 2)
}
res.push(temp)
}
return res
};
结果:
- 执行结果: 通过
- 执行用时:116 ms, 在所有 JavaScript 提交中击败了24.00%的用户
- 内存消耗:94.1 MB, 在所有 JavaScript 提交中击败了24.00%的用户
- 通过测试用例:30 / 30