旋转数组

旋转数组

将包含 n 个元素的数组向右旋转 步。

例如,如果  n = 7 ,  k = 3,给定数组  [1,2,3,4,5,6,7]  ,向右旋转后的结果为 [5,6,7,1,2,3,4]

注意:

尽可能找到更多的解决方案,这里最少有三种不同的方法解决这个问题。

感觉这个题目还是可以的。

首先要明白什么是一维数组右旋转几(当然肯定会有对应向左旋转几步喽,说不定也有向上或者向下旋转啦,害羞呵呵自己google了),你以为是像上学时候那样军训时原地旋转吗?其实我在很久以前刚触到的时候就是这么想的,我厉害吧。

码子可以说明一切:

[1,2,3,4,5,6,7]//初始数组
//向右旋转1步
[7,1,2,3,4,5,6]//向右旋转1步之后的数组
//再向右旋转1步,相对一最开始的数组就是向右旋转2步
[6,7,1,2,3,4,5]//向右旋转2步之后的数组
//把最原始的数组向左旋转1步
[2,3,4,5,6,7,1]//这就是向左旋转一步之后的数组

应该看明白了吧,就拿向右旋转1步来说:首先向拿旋转的数组要有一个初始的数组,是相对于一个数组来说向左或者向右的;向右旋转1步就是说把初始数组的最高位上的数字放置在数组的最低位置,让后其他位置上的数字都把自身的位置提高1位。就这么简单什么向左旋转都一个道理(程序员都爱说一些高大上的名词。听起来很牛逼,说穿了哎。。。)

其实这就很容易想到第一种方案:

private static int[] Rotate2(int[] nums, int k)//k就是指旋转几步
        {
            int length = nums.Length;
            while (k > 0)//循环几次就看k是多少
            {
                int t = 0;
                t = nums[length - 1];//这是获取数组最高位置上的数字
                for (int j = length - 2; j >= 0; j--)//从倒数第二个数字开始,倒叙循环。循环主要目的就是把其他数字位置都抬高一位
                {
                    nums[j + 1] = nums[j];
                }
                nums[0] = t;//抬高玩其他的,就可以直接把最高位上的数字赋值到0号位上了
                k--;//完成一个循环
            }
            return null;
        }

其实上面每一次循环就三步:第一获取最高位的数字,第二把其他位上的数字都抬高一位,第三把最初获得最高位的数字赋值到最低位置上。

第二种方法就比较取巧了:

 private static int[] Rotate1(int[] nums, int k)
        {
            int[] result = new int[nums.Length];//根据nums数组长度生成和其一样长度的数组
            for (int i = 0; i < nums.Length; i++)
            {
                result[(i + k) % nums.Length] = nums[i];//这里用到了取余,也是这个方法的核心
            }
            return result;
        }

为什么用取余上个例子:

    ///3元素在数组中的2位置上,(2+3) % 7 = 5
    ///5元素在数组中的4位置上,(4+3) % 7 = 0
    ///6元素在数组中的5位置上,(5+3) % 7 = 1
    ///7元素在数组中的6位置上,(6+3) % 7 = 2

长度为7的数组,向右旋转3步,数字的位置加3之后大于7的都要再从0号位置重新开始计算剩余的步子。这点特性就可以很好的用到求余。

应用一下:

        static int[] nums = new int[] { 1, 2, 3, 4, 5, 6, 7 };
        static void Main(string[] args)
        {
            //Rotate1(nums, 3);
            Rotate2(nums, 3);
        }

这种类型的题目还有很多种解法(自己可以google喽),以后愿意的话我再补充。






评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值