leetcode189-rotating array

Preface

2019.10.27 check-in

Algorithm is the method to solve the problem. The same problem, using different algorithms, although the results obtained are the same, but the time and resources consumed are different. This requires us to learn algorithms and find out which algorithm is better.

topic

One leetcode189 every day. Rotating array

Category: Array

Difficulty: easy

Title link: https://leetcode-cn.com/problems/rotate-array/

Title description

Given an array, move the elements in the array k positions to the right, where k is a non-negative number.

Example 1:

Input: [1,2,3,4,5,6,7] and k = 3
Output: [5,6,7,1,2,3,4]
Explanation:
Rotate right 1 step: [7,1 ,2,3,4,5,6]
Rotate right 2 steps: [6,7,1,2,3,4,5]
Rotate right 3 steps: [5,6,7,1,2,3 ,4]

Example 2:

Input: [-1, -100,3,99] and k = 2
Output: [3,99, -1, -100]
Explanation:
rotation to the right Step 1: [99, -1, -100,3]
to Rotate right 2 steps: [3,99,-1,-100]

Description:

  • Think of as many solutions as possible. There are at least three different ways to solve this problem.
  • It is required to use an in-place algorithm with a space complexity of O(1).

answer

do it yourself

  • Ideas

I'm too clever, I feel that moving in place is so complicated, I have to use extra memory to achieve it. That is to put the array into the list, because the list can operate on the head and tail, because every time you move one bit to the right, you can delete from the tail and insert the deleted element to the head.

  • Code
class Solution {
    public void rotate(int[] nums, int k) {
        ArrayList<Integer> list = new ArrayList<>();
        for(int i=0; i<nums.length; i  ){
            list.add(nums[i]);
        }
        for(int i = 0; i < k; i  ) {
            int target = list.remove(nums.length-1);
            list.add(0,target);
        }
        int[] array = new int[]{};
        for (int i =0;i<list.size();i  ) {
            nums[i] = list.get(i);
        }
    }
}

The code is relatively simple, and there is nothing to parse. Extra memory is used here to put the array elements in the list. It should not meet the requirements of the problem, but there is no way. After all, the algorithm is too slick, and there will be an optimal solution below.

  • Complexity analysis
  1. Time complexity: O(nnn) = O(n). for The time complexity of the loop is O(n), and a total of three for loops are used.
  2. Space complexity: O(n). The space required by the List is equal to the number of elements in nums.
  • Results of the

Reference solution

  • Ideas

This question provides the following two ideas:

  1. Double cycle:
    violence, the first cycle is the number that needs to be shifted to the right, and the second cycle moves all element values ​​to the correct position (this requires reflection, should be conceivable, but not recommended).
  2. Flip:
    arr = [1,2,3,4,5] --shift two bits to the right --> [4,5,1,2,3], assuming n = arr.length, k = right shift number, Available:

Flip the elements with index [0,n-1] --> [5,4,3,2,1]

Flip the elements between index [0,k-1] --> [4,5,3,2,1]

Flip the elements between index [k,n-1] --> [4,5,1,2,3]

Rotating an array is actually dividing the array into two parts. The key to solving the problem is
to move the latter part to the front while ensuring the original order . The overall flip of the array satisfies the second element, but disrupts the
original order of the array , so the two parts are flipped again at this time to restore them to the original order (after flipping and
then flipping, the original order will be restored ).

  • Code

    /**
     * 双重循环
     * 时间复杂度:O(kn)
     * 空间复杂度:O(1)
     */
    public void rotate_1(int[] nums, int k) {
        int n = nums.length;
        k %= n;
        for (int i = 0; i < k; i  ) {
            int temp = nums[n - 1];
            for (int j = n - 1; j > 0; j--) {
                nums[j] = nums[j - 1];
            }
            nums[0] = temp;
        }
    }

    /**
     * 翻转
     * 时间复杂度:O(n)
     * 空间复杂度:O(1)
     */
    public void rotate_2(int[] nums, int k) {
        int n = nums.length;
        k %= n;
        reverse(nums, 0, n - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, n - 1);
    }


    private void reverse(int[] nums, int start, int end) {
        while (start < end) {
            int temp = nums[start];
            nums[start  ] = nums[end];
            nums[end--] = temp;
        }
    }

  • Algorithm complexity analysis

Double for loop:

  • Time complexity: O(n∗k)
  • Space complexity: O(1)

Flip:

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

Results of the

Flip execution results:

Concluding remarks

My friends may feel very clever after seeing the flipping solution, how they came up with it. I don’t think we need to be too entangled in this. We contact the algorithm problem itself, which is a deliberate process of improvement. If we do more, we will naturally have ideas.
[This article was first published on this site, please indicate the source for reprinting]: http://coderluo.top

If you are interested in the article, you can follow me on WeChat to exchange and learn together:WeChat scan code

Guess you like

Origin blog.csdn.net/taurus_7c/article/details/102768218