-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path189-RotateArray.go
More file actions
89 lines (76 loc) · 3.46 KB
/
189-RotateArray.go
File metadata and controls
89 lines (76 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package main
// 189. Rotate Array
// Given an integer array nums, rotate the array to the right by k steps, where k is non-negative.
// Example 1:
// Input: nums = [1,2,3,4,5,6,7], k = 3
// Output: [5,6,7,1,2,3,4]
// Explanation:
// rotate 1 steps to the right: [7,1,2,3,4,5,6]
// rotate 2 steps to the right: [6,7,1,2,3,4,5]
// rotate 3 steps to the right: [5,6,7,1,2,3,4]
// Example 2:
// Input: nums = [-1,-100,3,99], k = 2
// Output: [3,99,-1,-100]
// Explanation:
// rotate 1 steps to the right: [99,-1,-100,3]
// rotate 2 steps to the right: [3,99,-1,-100]
// Constraints:
// 1 <= nums.length <= 10^5
// -2^31 <= nums[i] <= 2^31 - 1
// 0 <= k <= 10^5
// Follow up:
// Try to come up with as many solutions as you can. There are at least three different ways to solve this problem.
// Could you do it in-place with O(1) extra space?
import "fmt"
// 时间复杂度 O(n),空间复杂度 O(1)
// 末尾 k mod n 个元素移动至了数组头部,剩下的元素右移 k mod n 个位置至最尾部。确定了最终态以后再变换就很容易。
// 先将数组中所有元素从头到尾翻转一次,尾部的所有元素都到了头部,然后再将 [0,(k mod n) − 1] 区间内的元素翻转一次,
// 最后再将 [k mod n, n − 1] 区间内的元素翻转一次,
func rotate(nums []int, k int) {
k %= len(nums)
reverse := func(a []int) {
for i, n := 0, len(a); i < n/2; i++ {
a[i], a[ n-1-i ] = a[ n-1-i ], a[i]
}
}
reverse(nums) // 先将数组中所有元素从头到尾翻转一次,尾部的所有元素都到了头部,
//fmt.Printf("reverse(nums) = %v\n",nums)
reverse(nums[:k]) // 再将 [0,(k mod n) − 1] 区间内的元素翻转一次
//fmt.Printf("reverse(nums[:k]) = %v\n",nums)
reverse(nums[k:]) // 再将 [k mod n, n − 1] 区间内的元素翻转一次
//fmt.Printf("reverse(nums[k:]) = %v\n",nums)
}
// 时间复杂度 O(n),空间复杂度 O(n)
// 使用一个额外的数组,先将原数组下标为 i 的元素移动到 (i+k) mod n 的位置,再将剩下的元素拷贝回来即可。
func rotate1(nums []int, k int) {
newNums := make([]int, len(nums))
// 先将原数组下标为 i 的元素移动到 (i+k) mod n 的位置
for i, v := range nums {
//fmt.Printf("(i+k) %% len(nums) = %v\n", (i+k) % len(nums))
newNums[(i+k) % len(nums)] = v
}
copy(nums, newNums) // 再将剩下的元素拷贝回来
}
func main() {
// rotate 1 steps to the right: [7,1,2,3,4,5,6]
// rotate 2 steps to the right: [6,7,1,2,3,4,5]
// rotate 3 steps to the right: [5,6,7,1,2,3,4]
nums1 := []int{ 1,2,3,4,5,6,7 }
fmt.Printf("before: nums1 = %v\n", nums1) // nums = [1,2,3,4,5,6,7], k = 3
rotate(nums1, 3)
fmt.Printf("after: nums1 = %v\n", nums1) // [5,6,7,1,2,3,4]
// rotate 1 steps to the right: [99,-1,-100,3]
// rotate 2 steps to the right: [3,99,-1,-100]
nums2 := []int{ -1,-100,3,99 }
fmt.Printf("before: nums2 = %v\n", nums2) // [-1,-100,3,99]
rotate(nums2, 2)
fmt.Printf("after: nums2 = %v\n", nums2) // [3,99,-1,-100]
nums11 := []int{ 1,2,3,4,5,6,7 }
fmt.Printf("before: nums11 = %v\n", nums11) // nums = [1,2,3,4,5,6,7], k = 3
rotate1(nums11, 3)
fmt.Printf("after: nums11 = %v\n", nums11) // [5,6,7,1,2,3,4]
nums12 := []int{ -1,-100,3,99 }
fmt.Printf("before: nums12 = %v\n", nums12) // [-1,-100,3,99]
rotate1(nums12, 2)
fmt.Printf("after: nums12 = %v\n", nums12) // [3,99,-1,-100]
}