leetcode-java-乐团站位

题目描述

某乐团的演出场地可视作 num * num 的二维矩阵 grid(左上角坐标为 [0,0]),每个位置站有一位成员。乐团共有 9 种乐器,乐器编号为 1~9,每位成员持有 1 个乐器。

为保证声乐混合效果,成员站位规则为:自 grid 左上角开始顺时针螺旋形向内循环以 1,2,…,9 循环重复排列。例如当 num = 5 时,站位如图所示

在这里插入图片描述

请返回位于场地坐标 [Xpos,Ypos] 的成员所持乐器编号。

我的解法

class Solution {
    public int orchestraLayout(int num, int xPos, int yPos) {
        int[][] grids = new int[num][num];
        int number=1;
        int x_up=0,x_down=num-1,y_left=0,y_right=num-1;
        while(y_right>=y_left&&x_up<=x_down){
            //首先y向右添加
            for(int i=y_left;i<=y_right;i++){
                grids[x_up][i]=number++;
                if(number>9){number%=9;}
            }
            x_up++;
            //x向下添加
            for(int j=x_up;j<=x_down;j++){
                grids[j][y_right]=number++;
                if(number>9){number%=9;}
            }
            y_right--;  
            //y向左添加
            for(int m=y_right;m>=y_left;m--){
                grids[x_down][m]=number++;
                if(number>9){number%=9;}
            }
            x_down--;
            //x向上添加
            for(int n=x_down;n>=x_up;n--){
                grids[n][y_left]=number++;
                if(number>9){number%=9;}
            }
            y_left++;
        }
        return grids[xPos][yPos];
    }
}

官方解法

思路:
1.获取所求点在第几层
2.前第0,1…k层的数量和 与 所求点相对第k层左上角元素(第k层的入口元素)的相对路径做+或-运算,求得所求点的绝对路径(从起始点到所求点经过的长度)
在这里插入图片描述

记:k(0,1,2…⌈n/2⌉ (往上取整))
C(k)=第k层的方块数目,如图C(0)=16,C(1)=8,C(2)=1;
T(k)=第k层以外(不包括第k层)的方块 数目,如图T(0)=0,T(1)=C(0)=16,T(2)=C(0)+C(1)=16+8=24,T(3)=16+8+1=25;
但是具体怎么计算呢 可以用补集的思想
T(k)=nn-(n-2k)(n-2k)=4k(n-k)

但是怎么求(i,j)点所在层 已经遍历过的数目呢 。(即下图深蓝色的路径长度)
1.求所在的层数k
k=min(x,n-1-x,y,n-1-y)(后续由于要分类讨论,k的求取可以直接通过其中某两个值求最小值即可); 即看该点距离哪个边界更近,所求的最小值就是第几层,如图 k=min(2,2,3,1),即处于第一层。那么我们也就知道了该层以外的橙色数目T(k)=T(1)=16。

2.求所求点(x,y)相对该层左上角点的相对路径长度

2.1 对于x<=y,我们可以知道dl=(x-k)+(y-k)+1
故 绝对路径长度为 T(k)+dl
在这里插入图片描述

2.2 但是对于x>y呢
如果我们采用相同的方法,就会导致对称的两个(i,j)与(j,i)相对路径相同。故才用另外一种方法,在计算层数k的时候 多计算一层内圈,再退dl-2个路径此时绝对路径长度为 T(k+1)-dl ,dl=(x-k)+(y-k)-1
在这里插入图片描述

(至于为何此处可直接-dl,可以看下图,下一层的入口点与上一层的入口点是右下和左上关系,按照螺旋顺序到(i,j)点的路径长度是相同的。)

最后, 就是把相应的路径长度len转化为1-9的数字即可,考虑到9%9=0,index=(len-1)%9+1。

当然此题也可拓展到mn型的矩阵,最后一圈应该是一条线。nn可以看作是m*n的特例,对于n为奇数的情况,一条线压缩成了一个点。

class Solution {
    public int orchestraLayout(int num, int xPos, int yPos) {
        long n=num,x=xPos,y=yPos;
        long k=Math.min(x,Math.min(y,Math.min(n-x-1,n-y-1)));
        if  (x <= y) {
            return  (int)((4*k*(n-k)+1+(x-k)+(y-k)-1)%9+1);
        } 
        return  (int)((4*(k+1)*(n-k-1)+1-(x-k)-(y-k)-1)%9+1);
    }
}

在这里插入图片描述

官方解法

我的解决方法中输出了整个表的数据,实际上他是个找规律的题目。
取余要考虑到9%9=0,所以要做一下改变。
找规律的过程会花很长时间,但是主要用到的思想还是补集
在计算单圈个数的时候,是用外圈减去内圈
计算单圈偏移的时候,两种情况,一种是直接计算,一种是整圈算下来减去直接计算的结果再消除误差。很简单,但是如果没想到就会算得很麻烦还百思不得其解,我大概是脑子秀逗了,看了好久才看明白。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问。 4. 查找特殊字符:如果乱码问只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值