编程语言
首页 > 编程语言> > 程序员面试金典 - 面试题 05.08. 绘制直线

程序员面试金典 - 面试题 05.08. 绘制直线

作者:互联网

题目难度: 中等

原题链接

今天继续更新程序员面试金典系列, 大家在公众号 算法精选 里回复 面试金典 就能看到该系列当前连载的所有文章了, 记得关注哦~

题目描述

绘制直线。有个单色屏幕存储在一个一维数组中,使得 32 个连续像素可以存放在一个 int 里。屏幕宽度为 w,且 w 可被 32 整除(即一个 int 不会分布在两行上),屏幕高度可由数组长度及屏幕宽度推算得出。请实现一个函数,绘制从点(x1, y)到点(x2, y)的水平线。

给出数组的长度 length,宽度 w(以比特为单位)、直线开始位置 x1(比特为单位)、直线结束位置 x2(比特为单位)、直线所在行数  y。返回绘制过后的数组。

示例 1:

示例 2:

题目思考

  1. 可以使用什么位运算来尽可能减少操作次数?

解决方案

思路

复杂度

代码

Python 3
class Solution:
    def drawLine(self, length: int, w: int, x1: int, x2: int,
                 y: int) -> List[int]:
        # 初始化长度为 length 的数组, 将其值全部设为 0, 代表空白屏幕
        res = [0] * length
        # w//32代表每一行有多少个数字, 乘以直线所在行数y, 即得到直线所在行的起点对应的数组下标
        startIndex = y * (w // 32)
        # 通过x1和x2除以32得到偏移量, 再与直线所在行起点下标相加, 从而得到s和e
        s = startIndex + x1 // 32
        e = startIndex + x2 // 32
        for i in range(s + 1, e):
            # 将(s,e)区间的数字的全部位赋值为1
            res[i] = -1
        # posMx代表正数最大值, 如果超过这个值的话需要手动转成负数
        posMx = 0x7FFFFFFF
        mx = 0xFFFFFFFF
        if s == e:
            # 如果s和e相等, 则变更的位数是当前这个数字[x1 % 32, x2 % 32]区间的位
            # 注意右边是低位, 所以mask是1 << (31 - b), 也即第31位对应的是数字1, 下同
            for b in range(x1 % 32, x2 % 32 + 1):
                mask = 1 << (31 - b)
                res[s] |= mask
            if res[s] > posMx:
                # 超出32位正数表示范围时, 需要额外转成32位负数表示, 下同
                res[s] = ~(mx ^ res[s])
        else:
            # 如果s和e相等, 则变更的位数是s的[x1 % 32, 31]区间以及e的[0, x2 % 32]的位
            for b in range(x1 % 32, 32):
                mask = 1 << (31 - b)
                res[s] |= mask
            for b in range(x2 % 32 + 1):
                mask = 1 << (31 - b)
                res[e] |= mask
            if res[s] > posMx:
                res[s] = ~(mx ^ res[s])
            if res[e] > posMx:
                res[e] = ~(mx ^ res[e])
        return res

大家可以在下面这些地方找到我~

标签:面试题,05.08,int,金典,res,数组,32,x2,x1
来源: https://blog.csdn.net/zjulyx1993/article/details/117586707