【LeetCode】每日一题 面试题 05.08. 绘制直线

52 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第22天,点击查看活动详情

面试题 05.08. 绘制直线

已知一个由像素点组成的单色屏幕,每行均有 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 <= 10^5
1 <= w <= 3 * 10^5
0 <= x1 <= x2 < w
0 <= y <= 10

解题思路

创建一个总共有length*32像素的数组并置位为0后合并为字符串
拼接字符串,将x1~x2替换为1(其实题目到这里就该结束了,没想到之后才是噩梦)
题目要求返回一个int类型的数组,所以先按照每32位一组进行分割
拿到32位字符串后有两种情况要考虑:正数与负数
正数情况:直接parseInt完事
负数情况:特征为高位为1,先转换为2进制减1再取反(注意取反符号~直接帮我们转换为十进制int了),最后乘上-1
将其按顺序压入数组,返回,结束

代码实现

/**
 * @param {number} length: how many int(32 bits)
 * @param {number} w: how many int in a row
 * @param {number} x1
 * @param {number} x2
 * @param {number} y: the number of row(start from 0)
 * @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 result = [];
  for (let i = 0; i < length * 32; i += 32) {
    let temp = str.substring(i, i + 32);
    if (temp[0] === "1") {
      temp = ~(parseInt(temp, 2) - 1);
      temp *= -1;
    }else {
      temp = parseInt(temp, 2);
    }
    result.push(temp);
  }
  return result;
};

如果你对这道题目还有疑问的话,可以在评论区进行留言;