轮转数组(第9题)

128 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

菜鸟就要从第9题继续

一、题目描述:

给你一个数组,将数组中的元素向右轮转 k **个位置,其中 k **是非负数。

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/ro… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思路分析:

第一版:直观来想,在不限制原位替换的情况下,只要一个新的数组,按照规则进行轮转计算即可,通过i+k对n求余就可以求出新数组的值,然后循环替换。

环状替换的思路就是根据1个1个依次进行替换,若循环完一次则进行下一次循环,直至完成所有。这块有一个关键点就是要判断要走多少个环,求最大公约数,这里还用了递归。 这个如果我直接写,回写成换一个位置加一计数,没有找到最大公约的内在规律。

最后一个方法,数组翻转很有意思,当我们将数组的元素向右移动k次后,尾部k%n个元素会移动至数组头部,其余元素向后移动k%n个位置。这里先将所有元素翻转,这样尾部的 k%n个元素就被移至数组头部,然后我们再翻转 [0, k%n-1]区间的元素和 [k%n,n−1] 区间的元素即能得到最后的答案。 这个如果我来写,可能不会单独拿出一个函数来做数组传入start和end来做翻转,而回直接输入数组最后再拼接,虽然思路清晰但不够通用。

三、AC 代码:

1、第一版

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var rotate = function(nums, k) {
    const n=nums.length
    let newNums =new Array()
    for (let i = 0; i < n; ++i) {
        newNums[(i + k) % n] = nums[i];
    }
    for (let y = 0; y < n; ++y) {
        nums[y] = newNums[y];
    }
};

2、环状替换

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {void} Do not return anything, modify nums in-place instead.
 */
const gcd = (x, y) => y ? gcd(y, x % y) : x;
var rotate = function(nums, k) {
    const n = nums.length;
    k = k % n;
    let count = gcd(k, n);
    for (let start = 0; start < count; ++start) {
        let current = start;
        let prev = nums[start];
        do {
            const next = (current + k) % n;
            const temp = nums[next];
            nums[next] = prev;
            prev = temp;
            current = next;
        } while (start !== current);
    }
};

3、数组翻转

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {void} Do not return anything, modify nums in-place instead.
 */
const reverse = (nums, start, end) => {
    while (start < end) {
        const temp = nums[start];
        nums[start] = nums[end];
        nums[end] = temp;
        start += 1;
        end -= 1;
    }
}
var rotate = function(nums, k) {
    k %= nums.length;
    reverse(nums, 0, nums.length - 1);
    reverse(nums, 0, k - 1);
    reverse(nums, k, nums.length - 1);
};