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();
        }
总结:个人最推崇的解法是解法一,题目不算难,但需要理清思路,然后具体写代码也可能会有问题。

猜你喜欢

转载自blog.csdn.net/a_clear_chen/article/details/80649502