generated from NikiforovAll/leetcode-playground-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path189.rotate-array.cs
168 lines (164 loc) · 4.45 KB
/
189.rotate-array.cs
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*
* @lc app=leetcode id=189 lang=csharp
*
* [189] Rotate Array
*
* https://leetcode.com/problems/rotate-array/description/
*
* algorithms
* Easy (33.94%)
* Likes: 2583
* Dislikes: 783
* Total Accepted: 467.1K
* Total Submissions: 1.4M
* Testcase Example: '[1,2,3,4,5,6,7]\n3'
*
* Given an array, rotate the array to the right by k steps, where k is
* non-negative.
*
* Follow up:
*
*
* Try to come up as many solutions as you can, there are at least 3 different
* ways to solve this problem.
* Could you do it in-place with O(1) extra space?
*
*
*
* 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 <= 2 * 10^4
* It's guaranteed that nums[i] fits in a 32 bit-signed integer.
* k >= 0
*
*
*/
using System;
namespace _189
{
// @lc code=start
public class Solution
{
public void Rotate(int[] nums, int k)
{
Solution3(nums, k);
}
// use additional O(k) space to store prefix
// shift elements in a linear time and restore prefix
private void Solution1(int[] nums, int k)
{
var shift = k % nums.Length;
var prefix = new int[shift];
for (int i = 0; i < shift; i++)
{
prefix[i] = nums[nums.Length - shift + i];
}
for (int i = nums.Length - 1; i >= shift; i--)
{
nums[i] = nums[i - shift];
}
for (int i = 0; i < shift; i++)
{
nums[i] = prefix[i];
}
}
// in-place solution
// time-out O(n x k)
private void Solution0(int[] nums, int k)
{
for (int i = 0; i < k; i++)
{
Shift();
}
void Shift()
{
var prefix = nums[^1];
for (int i = nums.Length - 1; i > 0; i--)
{
nums[i] = nums[i - 1];
}
nums[0] = prefix;
}
}
private void Solution3(int[] nums, int k)
{
int pivot = k % nums.Length;
var length = nums.Length - 1;
ReverseSubArray(nums, 0, length);
ReverseSubArray(nums, 0, pivot - 1);
ReverseSubArray(nums, pivot, length);
// Reverse(nums);
// Reverse(nums.AsSpan(0, pivot));
// Reverse(nums.AsSpan(pivot));
// static void Reverse(Span<int> arr)
// {
// var length = arr.Length - 1;
// for (int i = 0; i < arr.Length / 2; i++)
// {
// (arr[i], arr[length - i]) = (arr[length - i], arr[i]);
// }
// }
static void ReverseSubArray(int[] arr, int start, int end)
{
while (start < end)
{
(arr[start], arr[end]) = (arr[end], arr[start]);
start++;
end--;
}
}
// static void ReverseSubArray(int[] arr, int start, int end)
// {
// var pivot = start + (end - start) / 2;
// var length = end - start - 1;
// for (int i = start; i <= pivot; i++)
// {
// (arr[i], arr[end - i + start]) = (arr[end - i + start], arr[i]);
// }
// }
}
// Cyclic replacement
private void Solution4(int[]nums, int k)
{
k %= nums.Length;
var count = 0;
for (int start = 0; count < nums.Length; start++)
{
var current = start;
var prev = nums[start];
do
{
var next = (current + k) % nums.Length;
var temp = nums[next];
nums[next] = prev;
prev = temp;
count++;
} while (start != current);
}
}
}
// @lc code=end
}