Rotate Array

题目大意:

Rotate an array of n elements to the right by k steps.

For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4].

Note:
Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.

解答:

k就是从最后一个转到第一个的次数。 如上图, k=3,就将7、6、5分别转到最左边。


1.首先是自己的答案

轮流去替换:i -> (i+k)%len   这里注意:可能轮流一轮下来,并不是每个都能替换到。比如:{1,2,3,4,5,6},k=2,这里轮流替换的为{1,3,5}、{2,4,6}才结束。因此需要一个变量来记录有没有每个都轮到num++,然后每轮的开头,分别从0,1...开始,直到每个都轮到:num==len.

class Solution {
public:
    void swap(int& a, int& b){
        a = a ^ b;
        b = a ^ b;
        a = a ^ b;
    }

    void rotate(vector<int>& nums, int k) {
        int len = nums.size();
        if(k>=len)
            k = k%len;
        if(k == 0)
            return;
        int i = 0;
        int start = 0;
        int temp = nums[i];
        i = i+k;
        int num = 0;
        while(num < len){
            while(i != start){
                swap(nums[i],temp);
                i = (i+k)%len;
                num++;
            }
            num++;
            nums[i] = temp;
            start++;
            i = start;
            temp = nums[i];
            i = (i+k)%len;
        }
    }
};

2.这里引入leetcode中大神总结的5种方法,其中我的方法就是他的第二种方法。

注:以下方法是借用他人的,放在这只为自己以后能参考别人优秀代码而方便,并不是要盗取人家的知识,我在这声明,为了尊重知识产权


1. Make an extra copy and then rotate.

Time complexity: O(n). Space complexity: O(n).

    class Solution 
    {
    public:
        void rotate(int nums[], int n, int k) 
        {
            if ((n == 0) || (k <= 0))
            {
                return;
            }

            // Make a copy of nums
            vector<int> numsCopy(n);
            for (int i = 0; i < n; i++)
            {
                numsCopy[i] = nums[i];
            }

            // Rotate the elements.
            for (int i = 0; i < n; i++)
            {
                nums[(i + k)%n] = numsCopy[i];
            }
        }
    };

2. Start from one element and keep rotating until we have rotated n different elements.

Time complexity: O(n). Space complexity: O(1).


class Solution 
    {
    public:
        void rotate(int nums[], int n, int k) 
        {
            if ((n == 0) || (k <= 0))
            {
                return;
            }

            int cntRotated = 0;
            int start = 0;
            int curr = 0;
            int numToBeRotated = nums[0];
            int tmp = 0;
            // Keep rotating the elements until we have rotated n 
            // different elements.
            while (cntRotated < n)
            {
                do
                {
                    tmp = nums[(curr + k)%n];
                    nums[(curr+k)%n] = numToBeRotated;
                    numToBeRotated = tmp;
                    curr = (curr + k)%n;
                    cntRotated++;
                } while (curr != start);
                // Stop rotating the elements when we finish one cycle, 
                // i.e., we return to start.

                // Move to next element to start a new cycle.
                start++;
                curr = start;
                numToBeRotated = nums[curr];
            }
        }
    };


3. Reverse the first n - k elements, the last k elements, and then all the n elements.

Time complexity: O(n). Space complexity: O(1).

class Solution 
    {
    public:
        void rotate(int nums[], int n, int k) 
        {
            k = k%n;

            // Reverse the first n - k numbers.
            // Index i (0 <= i < n - k) becomes n - k - i.
            reverse(nums, nums + n - k);

            // Reverse tha last k numbers.
            // Index n - k + i (0 <= i < k) becomes n - i.
            reverse(nums + n - k, nums + n);

            // Reverse all the numbers.
            // Index i (0 <= i < n - k) becomes n - (n - k - i) = i + k.
            // Index n - k + i (0 <= i < k) becomes n - (n - i) = i.
            reverse(nums, nums + n);
        }
    };


4. Swap the last k elements with the first k elements.

Time complexity: O(n). Space complexity: O(1).

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        int n = nums.size();
        if (k%n == 0) return;
        int first = 0, middle = n-k%n, last = n;
        int next = middle;
        while(first != next) {
            swap (nums[first++], nums[next++]);
            if (next == last) next = middle;
            else if (first == middle) middle = next;
        }
    }
}; 


5. Keep swapping two subarrays.

Time complexity: O(n). Space complexity: O(1).


class Solution 
{
public:
    void rotate(int nums[], int n, int k) 
    {
        if ((n == 0) || (k <= 0) || (k%n == 0))
        {
            return;
        }

        k = k%n;
        // Rotation to the right by k steps is equivalent to swapping 
        // the two subarrays nums[0,...,n - k - 1] and nums[n - k,...,n - 1].
        int start = 0;
        int tmp = 0;
        while (k > 0)
        {
            if (n - k >= k)
            {
                // The left subarray with size n - k is longer than 
                // the right subarray with size k. Exchange 
                // nums[n - 2*k,...,n - k - 1] with nums[n - k,...,n - 1].
                for (int i = 0; i < k; i++)
                {
                    tmp = nums[start + n - 2*k + i];
                    nums[start + n - 2*k + i] = nums[start + n - k + i];
                    nums[start + n - k + i] = tmp;
                }

                // nums[n - 2*k,...,n - k - 1] are in their correct positions now.
                // Need to rotate the elements of nums[0,...,n - k - 1] to the right 
                // by k%n steps.
                n = n - k;
                k = k%n;
            }
            else
            {
                // The left subarray with size n - k is shorter than 
                // the right subarray with size k. Exchange 
                // nums[0,...,n - k - 1] with nums[n - k,...,2*(n - k) - 1].
                for (int i = 0; i < n - k; i++)
                {
                    tmp = nums[start + i];
                    nums[start + i] = nums[start + n - k + i];
                    nums[start + n - k + i] = tmp;
                }

                // nums[n - k,...,2*(n - k) - 1] are in their correct positions now.
                // Need to rotate the elements of nums[n - k,...,n - 1] to the right 
                // by k - (n - k) steps.
                tmp = n - k;
                n = k;
                k -= tmp;
                start += tmp;
            }
        }
    }
};

你可能感兴趣的:(LeetCode,C++,array)