leetcode 力扣 1196 绘制直线 题解 算法题

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

题目:绘制直线
绘制直线。

有个单色屏幕存储在一个一维数组中,使得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为画一条直线,屏幕表示为[0b00000000000000000 0000000000000011]
示例2:
输入:length = 3, w = 96, x1 = 0, x2 = 95, y = 0
输出:[-1, -1, -1]
语言:java
class Solution {
public int[] drawLine(int length, int w, int x1, int x2, int y) {
int[] ans = new int[length];
int size = length * 32, left = y * w + x1, right = y * w + x2, num = 0;
for (int i = 0; i < size; i++) {
int power = 31 - i % 32;
// 画线的区域,bit为1
if (i >= left && i <= right) num += 1 << power;
// 非画线区域,bit为0
else num += 0 << power;
// 每32位一个数字,0 ~ 31
if (i % 32 == 31) {
ans[i / 32] = num;
num = 0;
}
}
return ans;
}
}
语言:java
class Solution {
public int[] drawLine(int length, int w, int x1, int x2, int y) {
int[] ans=new int[length];
int low=(y*w+x1)/32;
int high=(y*w+x2)/32;
for(int i=low;i<=high;i++){
ans[i]=-1;
}
ans[low]=ans[low]>>>x1%32;
ans[high]=ans[high]&Integer.MIN_VALUE>> x2 % 32;
return ans;
}
}
语言:java
class Solution {
public int[] drawLine(int length, int w, int x1, int x2, int y) {
int[] ret = new int[length];
// 注意根据所在行数计算偏移量
int offset = y * w / 32;
// 首位数字下标
int head = x1 / 32 + offset;
// 末位数字下标
int rear = x2 / 32 + offset;
// 把涉及到的数全部置 -1 也就是 0b11111111111111111111111111111111 for (int i = head; i <= rear; i++)
ret[i] = -1;
// 调整首位数字
ret[head] = ret[head] & -1 >>> x1 % 32;
// 调整末位数字
ret[rear] = ret[rear] & Integer.MIN_VALUE >> x2 % 32;
return ret;
}
}
语言:cpp
class Solution {
public:
vector<int> drawLine(int length, int w, int x1, int x2, int y) {
unsigned int cnt=0x80000000;高位为1000
int a=0;
vector<int> ans;
for(int i=0;i<y;++i){//把y行之前的int加入数组;
int n=w/32;
while(n!=0){
ans.push_back(0);
n--;
}
}
for(int j=0;j<=w;++j){
if(j>=x1&&j<=x2){//如果j在x1和x2之间;
a=a|cnt;//把j位置1;
}
cnt=cnt>>1;
if((j+1)%32==0){//将一个置换完成的int加入数组;
ans.push_back(a);
a=0;//恢复初值,为下一个int准备;
cnt=0x80000000;
}
}
if(length>w/32*(y+1)){//把剩下的int加入数组;
int m=length-w/32*(y+1);
for(int i=0;i<m;++i){
ans.push_back(0);
}
}
return ans;
}
};
语言:cpp
### 代码
```cpp
## 语言:cpp
```cpp
class Solution {
public:
vector<int> drawLine(int length, int w, int x1, int x2, int y) {
vector<int> res(length);
for(int i=x1,width=w/32;i<=x2;i++) res[width * y + (i / 32)] |= (1 << (31 - (i % 32)));
return res;
}
};
语言:golang
func drawLine(length int, w int, x1 int, x2 int, y int) []int {
res := make([]int, length)
for i := x1 / 32; i <= x2 / 32;i++ {
end, start := (i + 1) * 32 - 1, i * 32
if end > x2 { end = x2 }
if start < x1 { start = x1 }
end, start = end % 32, start % 32
res[y * w / 32 + i] = int(int32((1 << (end - start + 1) - 1) < < (31 - end)))
}
return res
}
语言:golang
func drawLine(length int, w int, x1 int, x2 int, y int) []int {
matrix := make([]int, length)
// 列数
cols := w / 32
// 第y行的起点
start := y * cols
for i := (x1 - 1) / 32; i <= (x2-1)/32; i++ {
pixel := int32(0)
for col := 0; col < 32; col++ {
x := i*32 + col
if x >= x1 && x <= x2 {
pixel |= 1 << (31 - col)
}
}
matrix[start+i] = int(pixel)
}
return matrix
}
// 一种巧妙的解法,合并多次位移操作
func drawLine2(length int, w int, x1 int, x2 int, y int) []int {
matrix := make([]int, length)
low := (w*y + x1) / 32
high := (w*y + x2) / 32
for i := low + 1; i < high; i++ {
matrix[i] = -1
}
ones := uint32(1<<32 - 1)
lowValue := ones >> (x1 % 32)
highValue := ones << (31 - x2%32)
if low == high {
highValue = lowValue & highValue
}
matrix[low] = int(int32(lowValue))
matrix[high] = int(int32(highValue))
return matrix
}
语言:golang
func drawLine(length int, w int, x1 int, x2 int, y int) []int {
lineCount := w / 32
rows := length/lineCount
start, end := x1/32, x2/32
startBit, endBit := x1%32, 31-x2%32
res := []int{}
for i := 0; i < rows; i++ {
l := make([]int, lineCount)
if i == y {
for i := start; i <= end; i++ {
l[i] = -1
}
if start == end {
l[start] = int(int32(uint32(l[start])>>(startBit+endBi
t)))
l[end] = int(int32(uint32(l[end])<<endBit))
} else {
l[start] = int(int32(uint32(l[start])>>(startBit)))
l[end] = int(int32(uint32(l[end])<<endBit))
}
}
res = append(res, l...)
}
return res
}
语言:python3
class Solution:
def drawLine(self, length: int, w: int, x1: int, x2: int, y: int) -> List[int]:
#########对Python3很不友好
dot = [[0 for _ in range(32)] for _ in range(length)]
for i in range (x1, x2 + 1):
idx = (w // 32) * y + (i // 32)
dot[idx][i%32] = 1
#print(dot)
res = []
for a in dot:
int_32bit = 0
if a[0] == 0: #是正数
for k in range(32):
int_32bit += a[k] * 2 ** (31-k)
else: #是负数
sign = -1
#正数原码=反码=补码。

负数补码 = 原码按位取反,末位+1
#1.先末位-1
for k in range(31, -1, -1):
if a[k] == 0:
a[k] = 1 #从前面借位,减的
else:
a[k] = 0 #借的那个,被借没了
break
#2.按位取反
for k in range(1, 32):
a[k] = 1 - a[k]
#3.计算数值部分
for k in range(1, 32):
int_32bit += a[k] * 2**(31-k)
#4.别忘了-
int_32bit *= (-1)
res.append(int_32bit)
return res
语言:javascript
/**
* @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;
};。

相关文档
最新文档