绘制直线。有个单色屏幕存储在一个一维数组中,使得32个连续像素可以存放在一个 int 里。屏幕宽度为w,且w可被32整除(即一个 int 不会分布在两行上),屏幕高度可由数组长度及屏幕宽度推算得出。请实现一个函数,绘制从点(x1, y)到点(x2, y)的水平线。
给出数组的长度 length,宽度 w(以比特为单位)、直线开始位置 x1(比特为单位)、直线结束位置 x2(比特为单位)、直线所在行数 y。返回绘制过后的数组。
示例1:
输入:length = 1, w = 32, x1 = 30, x2 = 31, y = 0
输出:[3]
说明:在第0行的第30位到第31为画一条直线,屏幕表示为[0b000000000000000000000000000000011]
示例2:
输入:length = 3, w = 96, x1 = 0, x2 = 95, y = 0
输出:[-1, -1, -1]
ans:存放所有像素,一共有length个
wid:每行有几个像素
n1:起始像素
m1:开始变化的位数
n1:终止像素
m1:最后变化的位数
class Solution:
def drawLine(self, length: int, w: int, x1: int, x2: int, y: int) -> List[int]:
ans=[0]*length
wid=w//32
n1,m1=divmod(x1,32)
n2,m2=divmod(x2,32)
#将所有变化的像素都置为-1
for i in range(wid*y+n1,wid*y+n2+1):
ans[i]=-1
#将不在区域里的位数置为0
if m1!=0:
ans[wid*y+n1]+=1<<(32-m1)
ans[wid*y+n2]-=(1<<(32-m2-1))-1
return ans
复杂版:
class Solution:
def drawLine(self, length: int, w: int, x1: int, x2: int, y: int) -> List[int]:
res = [0 for i in range(length)]
#每行的像素个数
m = w //32
#一共有几行
n = length * 32/ w
start = y*m +x1//32
#存放发生变化的像素
num = []
for i in range(x1//32*32, x2//32*32+32):
if x1<= i and i<= x2:
num.append(1)
else:
num.append(0)
cnt = len(num)//32
for i in range(cnt):
a = num[i*32:(i+1)*32]
flag = 1
#负数,因为python负数显示的问题,需要将补码手动转化成十进制数字
if a[0] == 1:
flag = 0
for j in range(31, -1, -1):
if a[j] == 0:
a[j] = 1
else:
a[j] = 0
break
for j in range(32):
if a[j] == 0:
a[j] =1
else:
a[j] = 0
b = 0
for k in range(32):
b = b + a[k] * pow(2,31-k)
if not flag:
b = b*(-1)
res[start] = b
start += 1
return res