Halo, 好久不见各位小伙伴,这几天工作是在是太忙了,忙到都没有足够的时间去继续写算法题目,那么今天一次性带来两道比较类似的题目,在LeetCode中属于中等难度的题目。但其实只要你掌握其中的要点,这一题其实跟简单的一样
那么今天带来的就是第54题,和59题。两题都涉及到旋转二维数组的概念。这两题分别是在说给定一个二维数组,按照螺旋的方式输出数字,以及按照螺旋的方式填充元素。其实都在描述的是同一个概念的东西
在LeetCode中同类型的题目,通常主要的「中心思想不变」只变其中参数偏多,这一题就把这个中心思想解释得淋漓尽致了。
我们要做旋转题目,我们必须要懂一个非常简单的概念,那么就是「上」、「下」、「左」、「右」的四个方向,没错就是这简单的四个方向,如果你没有很明确的思路的话,你会走不下去的。
接下来,我们先看一下图 这个图中的二维数组很简单,但是要你螺旋输出他,也就是「右->下->左->上」的顺序不断的重复这个步骤,但是我们要十分注重边界,因为每一次循环其实是一个边界的移动。
比方说,我们第一回合从第一行开始输出「1、2、3」 结束这3个输出以后,我们必须把「上边界」 往下挪动一行,因为当下一次循环到此处时,必须是「这一行」的「下一行」, 在这里没理解的小伙伴,我再举个例子从二维数组的右侧输出「3、6、9」此时的顺序是往下输出,但输出完后,「右边界」 必须往左挪动一行。
其实这个是有个口诀的「右移上加」、「下移右减」、「左移下减」、「上移左加」 记住这4个口诀以后,再来参考我们的code,先来看「题目54」
func spiralOrder(matrix [][]int) []int {
res := []int{}
if len(matrix) == 0{
return res
}
top := 0
right := len(matrix[0])-1
bottom := len(matrix) - 1
left := 0
direction := "right"
for left<=right && top <= bottom{
switch direction {
case "right":
for r:=left; r<=right; r++{
res = append(res, matrix[top][r])
}
top ++ //做完后 整个跳到下一行
direction = "bottom"
break
case "bottom":
for b:= top; b<=bottom; b++{
res = append(res, matrix[b][right])
}
right -- //做完后 整个右边往左靠一行
direction = "left"
break
case "left":
for l:= right; l>=left; l--{
res = append(res, matrix[bottom][l])
}
bottom -- //做完后 整个下面往上一行
direction = "top"
break
case "top":
for t:= bottom; t>=top; t--{
res = append(res, matrix[t][left])
}
left ++ //做完后 整个左边往右一行
direction = "right"
break
}
}
return res
}
这里为什么「left<=right 和 top<= bottom」 就是因为刚才所说的边界问题,如果说这里不<=的话,那么每一次循环就有其中一行的数据,我们是获取不到的了。
有了这个基础以后,你再来看「题目59」, 就什么事情都迎面而解了。
func generateMatrix(n int) [][]int {
res := make([][]int, n)
if n == 1{
tmp := []int{1}
res[0] = tmp
return res
}
if n > 1{
for a := range res{
res[a] = make([]int, n) //初始化二维数组
}
}
top := 0
right := n - 1
bottom := n - 1
left := 0
direction := "right"
count := 1
for left <= right && top <= bottom {
switch direction {
case "right":
for r := left; r <= right; r++ {
res[top][r] = count
count++
}
top++ //做完后 整个跳到下一行
direction = "bottom"
break
case "bottom":
for b := top; b <= bottom; b++ {
res[b][right] = count
count++
}
right-- //做完后 整个右边往左靠一行
direction = "left"
break
case "left":
for l := right; l >= left; l-- {
res[bottom][l] = count
count++
}
bottom -- //做完后 整个下面往上一行
direction = "top"
break
case "top":
for t:= bottom; t>=top; t--{
res[t][left] = count
count++
}
left ++ //做完后 整个左边往右一行
direction = "right"
break
}
}
return res
}
第59题目,就是初始化一个二维数组为「n的长度」然后往里面添加一个「count」然后,就没然后了,这两题非常简单。我会把我做的所有题目的代码都放在Github上哦,希望小伙伴们可以去点个star