1. 程式人生 > >LeetCode——旋轉陣列

LeetCode——旋轉陣列

問題描述:給定一個數組,將陣列中的元素向右移動 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();
        }
總結:個人最推崇的解法是解法一,題目不算難,但需要理清思路,然後具體寫程式碼也可能會有問題。