LeetCode——旋轉陣列
阿新 • • 發佈:2019-01-07
問題描述:給定一個數組,將陣列中的元素向右移動 k 個位置,其中 k 是非負數。
解法一:將下標為i的元素放在下標i+k處,再將下標i+k處的元素放置在正確位置,以此類推(AC),時間複雜度:O(n),空間複雜度:O(1),程式碼如下:
private static void Rotate1(int[] nums,int k) { if (k == 0) return; int count = 0; k = k % nums.Length; for(int start=0;count<nums.Length;++start) { int current = start; int pre = nums[start]; do { int next = (current + k) % nums.Length; int temp = nums[next]; nums[next] = pre; pre = temp; ++count; current = next; } while (current != start); } }
解法二:每次往後移一位,執行k次(當陣列很大且k較大時時間超出限制),時間複雜度:O(kn),空間複雜度:O(1);程式碼如下:
private static void Rotate2(int[] nums, int k) { if (k == 0 || nums.Length==1) return; if (k < 0) Console.WriteLine("Input wrong"); int length = nums.Length; int temp, previous; for(int i=0;i<k;++i) { previous = nums[length - 1]; for(int j=0;j<length;++j) { temp = nums[j]; nums[j] = previous; previous = temp; } } }
解法三:將整個陣列翻轉,再分別翻轉前後兩個部分(AC),時間複雜度:O(n),空間複雜度:O(1),程式碼如下:
private static void Rotate3(int[] nums, int k) { if(nums==null || k<0 ) { Console.WriteLine("Input wrong!"); return; } k = k % nums.Length; int end = nums.Length - 1; Reverse(nums, 0, end); Reverse(nums, 0, k - 1); Reverse(nums, k, end); } //翻轉 private static void Reverse(int[] nums,int start,int end) { if (nums == null || start < 0 || start > end) { return; } while(start<end) { int temp = nums[end]; nums[end] = nums[start]; nums[start] = temp; ++start; --end; } }
解法四:利用一個額外的陣列(leetcode AC),時間複雜度:O(n),空間複雜度:O(n),程式碼如下:
private static void Rotate4(int[] nums, int k)
{
if(nums==null || k<0)
{
Console.WriteLine("Imput wrong!");
return;
}
int[] a = new int[nums.Length];
for(int i=0;i<nums.Length;++i)
{
a[(i + k) % nums.Length] = nums[i];
}
for(int i=0;i<nums.Length;++i)
{
nums[i] = a[i];
}
}
Main方法如下:
static void Main(string[] args)
{
int[] nums = { 1, 2, 3, 4, 5, 6 };
Rotate1(nums, 2);
for (int i = 0; i < nums.Length; ++i)
Console.Write("{0} ", nums[i]);
Console.ReadKey();
}
總結:個人最推崇的解法是解法一,題目不算難,但需要理清思路,然後具體寫程式碼也可能會有問題。