zoukankan      html  css  js  c++  java
  • [LeetCode] 189. Rotate Array 旋转数组

    Given an array, rotate the array to the right by k steps, where k is non-negative.

    Example 1:

    Input: [1,2,3,4,5,6,7] and 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: [-1,-100,3,99] and 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]
    

    Note:

    • 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?

    解法1:用一个额外的复制空间。 Time complexity: O(n). Space complexity: O(n)

    解法2:翻转前n - k元素,翻转剩下的k个元素,最后翻转全部元素。O(n). Space complexity: O(1)   推荐解法2.

    解法3:每次把最后一个元素移到第一位,后面的元素后移一位,循环往复,直到第k次。

    解法4:交换最后k个元素和最开始的k个元素,在把前面的n-k个元素翻转。

    解法参考:LeetCode Discuss

    Java:

    public void rotate(int[] nums, int k) {
        k %= nums.length;
        reverse(nums, 0, nums.length - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, nums.length - 1);
    }
    
    public void reverse(int[] nums, int start, int end) {
        while (start < end) {
            int temp = nums[start];
            nums[start] = nums[end];
            nums[end] = temp;
            start++;
            end--;
        }
    }
    

    Python:  

    class Solution:
        def rotate(self, nums, k):
            k %= len(nums)
            self.reverse(nums, 0, len(nums))
            self.reverse(nums, 0, k)
            self.reverse(nums, k, len(nums))
    
        def reverse(self, nums, start, end):
            while start < end:
                nums[start], nums[end - 1] = nums[end - 1], nums[start]
                start += 1
                end -= 1  

    C++: 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];
                }
            }
        };
    

    C++: Reverse the first n - k elements, the last k elements, and then all the n elements.

     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);
            }
        };

     C++: Swap the last k elements with the first k elements.  Time complexity: O(n). Space complexity: O(1).

    class Solution 
    {
    public:
        void rotate(int nums[], int n, int k) 
        {
            for (; k = k%n; n -= k, nums += k)
            {
                // Swap the last k elements with the first k elements. 
                // The last k elements will be in the correct positions
                // but we need to rotate the remaining (n - k) elements 
                // to the right by k steps.
                for (int i = 0; i < k; i++)
                {
                    swap(nums[i], nums[n - k + i]);
                }
            }
        }
    };
    

    C++: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];
                }
            }
        };
    

      

      

    类似题目:

    [LeetCode] 151. Reverse Words in a String 翻转字符串中的单词 

    [LeetCode] 186. Reverse Words in a String II 翻转字符串中的单词 II

    [LeetCode] 557. Reverse Words in a String III 翻转字符串中的单词 III

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    【动态规划】CDOJ1651 Uestc的命运之旅
    【动态规划】【二分】CDOJ1006 最长上升子序列
    【动态规划】CDOJ1271 Search gold
    【概率dp】【滚动数组】CDOJ1652 都市大飙车
    【混合背包】CDOJ1606 难喝的饮料
    【状压dp】CDOJ1608 暑假集训
    【构造】CDOJ1607 大学生足球联赛
    【二分】Codeforces Round #417 (Div. 2) C. Sagheer and Nubian Market
    【动态规划】Codeforces Round #417 (Div. 2) B. Sagheer, the Hausmeister
    HBase简介
  • 原文地址:https://www.cnblogs.com/lightwindy/p/8644265.html
Copyright © 2011-2022 走看看