leetcode之Z-字形变换Golang
我解这道题的时候时间效率和空间效率感觉都不高,因为我用的是一个二维数组
二维数组的行数就是函数的入口参数numRows
二维数组的列数是通过一系列的计算得到的,我认为就是在这个地方浪费了空间,因为这个二维数组并没有全部存满,当numRows越大的时候,流出来的空闲的地方就越多:
设Z字形中竖着的一共有n列,待处理字符串长度length,那么有:
n*p+(p-2)*n>=length
从而可以得到一个n,
那么二维数组的列数为:column=n+n*(numRows-2)=n*(numRows-1)
然后就是这事行列两个坐标row和col
当填充z字形的竖着的地方的时候,行列坐标的变化为row++,而col不变,当row==numRows的时候开始填充斜着的地方
当填充z字形斜着的地方的时候,行列坐标的变化为row--,col++,当row==0的时候,开始填充竖着的地方
最后读取二维数组中不是\x00的值,注意这里不能空格,因为\x00!=空格
最后附上代码:
func convert(s string, numRows int) string {
if numRows == 1 {
return s
}
twoDimensionalResult := make([][]byte, numRows)
length := len(s)
n := 1
for {
if 2*n*(numRows-1) > length {
break
}
n++
}
n = n * (numRows - 1)
for i := 0; i < numRows; i++ {
twoDimensionalResult[i] = make([]byte, n)
}
row, col := 0, 0
flag := true
for i := 0; i < length; i++ {
twoDimensionalResult[row][col] = s[i]
if row == numRows-1 {
flag = false
} else if row == 0 {
flag = true
}
if flag {
row++
} else {
row--
col++
}
}
//在这里,因为已经为切片开辟了空间了,也就是说此时切片中有值,只不过全部是0值
// 所以下面不能用append,因为如果用append,那么新加入的数据是从所有的0值后面追加的,所以造成的结果就是输出的结果的字符串里面前面一大截是空格
resultSlice := make([]string, numRows)
for i := 0; i < numRows; i++ {
tmpStr := strings.ReplaceAll(string(twoDimensionalResult[i]), "\x00", "")
resultSlice[i] = tmpStr
}
return strings.Join(resultSlice, "")
}
另一种优化的解法
通过找规律可以快速的知道每一个位置的每个元素位于哪一行

上面两组数据分别是numRows等于4和5的情况,会排成4行或者5行
然后我们找规律,例如对于第一组数据
排在第一行的数据分别为0,6,12
排在第一列的数据分别为0,1,2,3
所以我们可以用求余的方式获取他们的位置,我的第一反应是用3来求余,但是用3不能区分第一行第一行和最后一行,而其他行都能一下求出来,所以就尝试用6来求余
当用6求余的时候,竖着排列的数据能够正确定位到位置,斜着排列的数据就要多处理一次:
例如对于编号为5的数据:
余数:5%6=5
行号:3-(5-3)=1
所以成功解决了斜着排列数据的位置
综上所述:
求余的数是n=2*numRows-2
对编号为k的数据:
p=k%n
if p<=numRows-1
那么p就是这个数据所在的行号
else:
p=numRows-1-(p-(numRows-1))=2*numRows-2-p
知道了每个数据所在的行号,我们就可以创建对应行的数组,然后将他们依次存入这些数组中,最后按行号读取每个数组的数据,组成最后的字符串输出
代码如下:
func convert(s string, numRows int) string {
if numRows == 1 {
return s
}
var retStr string
twoDimensionalResult := make([][]byte, numRows)
length := len(s)
n := 2*numRows - 2
for i := 0; i < length; i++ {
index := i % n
if index >= numRows {
// index=numRows-1-(index-(numRows-1))
// index=2*numRows-2-index
// 经过化简,上面两个式子等于下面这个式子,n=2*numRows-2
index = n - index
}
twoDimensionalResult[index] = append(twoDimensionalResult[index], s[i])
}
for i := 0; i < numRows; i++ {
retStr = retStr + string(twoDimensionalResult[i])
}
return retStr
}
浙公网安备 33010602011771号