本文共 2350 字,大约阅读时间需要 7 分钟。
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入:
[1,2,3,4,5,6,7] 和 k = 3 输出: [5,6,7,1,2,3,4] 解释: 向右旋转 1 步: [7,1,2,3,4,5,6] 向右旋转 2 步: [6,7,1,2,3,4,5] 向右旋转 3 步: [5,6,7,1,2,3,4]
示例 2:
输入:
[-1,-100,3,99] 和 k = 2 输出: [3,99,-1,-100] 解释: 向右旋转 1 步: [99,-1,-100,3] 向右旋转 2 步: [3,99,-1,-100]
说明:
方法一:执行34.66%,内存16.98%
创建一个切片temp
,遍历nums
,根据条件将值一个一个放入temp
func rotate1(nums []int, k int) { l := len(nums) //新建一个临时切片 temp := make([]int, l, l) // 去掉所有元素都循环过的次数 k = k % l // fmt.Println(k) //不需要循环直接跳出 if k == 0 { return } for i := range nums { j := i + k if j < l { temp[j] = nums[i] } else if j > l { temp[j-l] = nums[i] } else { temp[0] = nums[i] } // fmt.Println(temp, nums[i]) // temp = append(temp[l-1:], temp[:l-1]...) } //还给原切片 for i, v := range temp { nums[i] = v } // fmt.Printf("%T %v\n", nums, nums)}
方法二:执行95.39%,内存9.43%
利用内置函数append()
实现,但由于每次append()
,内存地址都会改变,因此也需要启用一个临时切片temp
。 只能使用append(nums[:0],temp...)
这种形式来保证nums
的地址不会改变。 func rotate2(nums []int, k int) { l := len(nums) k = k % l if k == 0 { return } // 效果与下面的评测结果一致 // nums = append(nums[:0], (append(nums[l-k:], nums[:l-k]...))...) //每一次append,内存地址都会改变, //新建一个临时切片 temp = append(nums[l-k:], nums[:l-k]...) //还给原切片 nums = append(nums[:0], temp...)}
方法三:执行8.57%,内存64.15%
这个思路就比较简单了,nums
元素的前一个值替换后一个,最后的值替换第一个。 这个方法都在nums
中操作,由于少了一个临时切片,内存开销大大降低。 func rotate3(nums []int, k int) { l := len(nums) k %= l // fmt.Println(k) if k == 0 { return } var temp int for i := 0; i < k; i++ { temp = nums[l-1] for j := l - 1; j >= 0; j-- { if j == 0 { nums[0] = temp } else { nums[j] = nums[j-1] } } }}
方法四:执行18.24%,内存100%
这个方法参考了内存占用排名第一的代码,与方法三几乎无疑,只是多了一个临时变量,并将nums[j] = num[j-1]
替换成了nums[j]=t1
,利用变量t1
和t2
之间进行替换,而不像方法三中切片直接nums[n]=nums[n-1]
交换值,虽然表面上多了一个变量,实际内存却占用更小。 func rotate4(nums []int, k int) { l := len(nums) k %= l // fmt.Println(k) if k == 0 { return } var t1, t2 int for i := 0; i < k; i++ { t1 = nums[l-1] for j := 0; j < l; j++ { t2 = nums[j] nums[j] = t1 t1 = t2 } }}
这道题到手的时候一度感觉特别简单,结果四个解题方法做了一天。。。真是够菜的!
其中注意的地方主要有:
append(nums[:0],temp)
这种形式来防止重置内存地址(前提是temp
内的元素个数与nums
中的一致),但这也提醒我们实际使用append()
时需密切注意内存的变化。转载地址:http://evkpi.baihongyu.com/