数据结构之数组旋转系列一

题目

给定一个大小为 N 的整数数组 arr[] 和一个整数,任务是将数组元素向左旋转 d 个位置。

Examples:

Input:
arr[] = {1, 2, 3, 4, 5, 6, 7}, d = 2
Output: 3 4 5 6 7 1 2
Input: arr[] = {3, 4, 5, 6, 7, 1, 2}, d=2
Output: 5 6 7 1 2 3 4

方法1:使用临时数组
  • 首先将索引 d 到 N-1 的元素存储到临时数组中。
  • 然后将原始数组的前 d 个元素存储到 temp 数组中。
  • 将临时数组的元素复制回原始数组
using System;

namespace csharptest
{
    public class GFG
    {
        public static void PrintTheArray(int[] arr, int n)
        {
            for (int i = 0; i < n; i++)
            {
                Console.Write(arr[i].ToString() + " ");
            }
        }

        public static void Rotate(int[] arr, int d, int n)
        {
            int[] temp = new int[n];

            int k = 0;
            for (int i = d; i < n; i++)
            {
                temp[k] = arr[i];
                k++;
            }

            for (int i = 0; i < d; i++)
            {
                temp[k] = arr[i];
                k++;
            }

            for (int i = 0; i < n; i++)
            {
                arr[i] = temp[i];
            }

        }

        static void Main(string[] args)
        {
            Console.WriteLine("Main start ...");

            int[] arr = {1, 2, 3, 4, 5, 6, 7};
            var N = arr.Length;
            var d = 2;

            GFG.Rotate(arr, d, N);
            GFG.PrintTheArray(arr, N);

            Console.WriteLine("\nMain end ...");
        }
    }
}

Output
3 4 5 6 7 1 2

时间复杂度:O(N)
空间杂度:O(N)

方法2:一个一个地旋转

思路:

  • 在每次迭代中,将元素循环向左移动一个位置(即,第一个元素变为最后一个元素)。
  • 执行此操作 d 次以将元素向左旋转 d 位置。

步骤:

  • 将数组向左旋转一个位置。 为此,请执行以下操作:
    将数组的第一个元素存储在临时变量中。
    将原始数组中的其余元素移动一位。
    使用临时变量更新数组的最后一个索引。
  • 对所需的左转次数重复上述步骤。
public static void Rotate2(int[] arr, int d, int n)
{
    var p = 1;
    while (p <= d)
    {
        var last = arr[0];
        for (int i = 0; i < n - 1; i++)
        {
            arr[i] = arr[i + 1];
        }
        arr[n - 1] = last;
        p++;
    }
    for (int i = 0; i < n; i++)
    {
        Console.Write(arr[i].ToString() + " ");
    }
}

时间复杂度:O(N * d)
空间杂度:O(1)

方法3:方法2的扩展

说明:

Let arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} and d = 3

First step:
        => First set is {1, 4, 7, 10}.
        => Rotate this set by one position to the left.
        => This set becomes {4, 7, 10, 1}
        => Array arr[] = {4, 2, 3, 7, 5, 6, 10, 8, 9, 1, 11, 12}

Second step:
        => Second set is {2, 5, 8, 11}.
        => Rotate this set by one position to the left.
        => This set becomes {5, 8, 11, 2}
        => Array arr[] = {4, 5, 3, 7, 8, 6, 10, 11, 9, 1, 2, 12}

Third step:
        => Third set is {3, 6, 9, 12}.
        => Rotate this set by one position to the left.
        => This set becomes {6, 9, 12, 3}
        => Array arr[] = {4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3}

步骤:

  • 执行 d%n 以将 d 的值保持在数组的范围内,其中 d 是数组旋转的次数,N 是数组的大小。
  • 计算 GCD(N, d) 以将数组划分为集合。
  • 从 0 到从 GCD 获得的值运行一个 for 循环。
    将 arr[i] 的值存储在一个临时变量中(i 的值表示集合数)。
    运行 while 循环以根据集合更新值。
  • 退出 while 循环后,将 arr[j] 的值分配为临时变量的值(j 的值表示第 i 个集合的最后一个元素)。
static int gcd(int a, int b)
{
    if (b == 0)
        return a;
    else
        return gcd(b, a % b);
}

static void leftRotate(int[] arr, int d, int n)
{
    int i, j, k, temp;
    /* To handle if d >= n */
    d = d % n;
    int g_c_d = gcd(d, n);
    for (i = 0; i < g_c_d; i++) {
        /* move i-th values of blocks */
        temp = arr[i];
        j = i;
        while (true) {
            k = j + d;
            if (k >= n)
                k = k - n;
            if (k == i)
                break;
            arr[j] = arr[k];
            j = k;
        }
        arr[j] = temp;
    }
}

时间复杂度:O(N)
空间杂度:O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值