力扣:05.08绘制直线

104 阅读1分钟

「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战

描述

绘制直线。有个单色屏幕存储在一个一维数组中,使得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]

解析

本题解题思路采用位运算,具体步骤如下:

class Solution {
    public int[] drawLine(int length, int w, int x1, int x2, int y) {
        int[] ans=new int[length];
        //i:行号
        for(int i=0;i<32*length/w;++i) {    
            if(i==y) {
                //对这一行中的各个整数分类处理
               for(int j=0;j<w/32;++j) {
                   //如果这个整数的最后一位大于x1,表明这个整数中会有一部分变为1
                   if((j+1)*32-1>=x1) {
                        //如果这个整数开头大于x1,结尾小于x2,则这个整数每位都是1
                       if(j*32>=x1 && (j+1)*32-1<=x2) ans[i*w/32+j]=-1;
                       else if(j*32>=x1 && (j+1)*32-1>x2) {
                           for(int k=0;k<=x2-j*32;++k) ans[i*w/32+j]=ans[i*w/32+j] | (1<<(31-k));
                       }
                        //如果这个整数开头小于x1,结尾小于等于x2
                       else if(j*32<x1 && (j+1)*32-1<=x2) {
                           for(int k=0;k<=(j+1)*32-1-x1;++k) ans[i*w/32+j]=ans[i*w/32+j] | (1<<k);
                       }
                        //如果这个整数开头小于x1,结尾大于x2
                       else if(j*32<x1 && (j+1)*32-1>x2) {
                           for(int k=0;k<=x2-x1;++k) ans[i*w/32+j]=ans[i*w/32+j] | (1<<((j+1)*32-1-x1-k));
                       }
                   }
               }
            }
        }
        return ans;
    }
}

运行结果:

执行结果:通过

执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户

内存消耗:38.6 MB, 在所有 Java 提交中击败了73.40%的用户