zoukankan      html  css  js  c++  java
  • C#解leetcode 189. Rotate Array

    Rotate an array of n elements to the right by k steps.

    For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4].

    Note:
    Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.

    我的代码,运行时间488ms:

    public class Solution {
        public void Rotate(int[] nums, int k) {     
          int[] zong=new int[nums.Length+k];
          int j=0;
           k=k%nums.Length;
            int[] temp=new int[k];
          if (k!=0)
          {
          for(int i=nums.Length-k;i<nums.Length;i++)
          {
              temp[j]=nums[i];
              j++;
          }
          temp.CopyTo(zong, 0); //将temp数组拷贝到zong数组中,其实位置为zong[0]
          nums.CopyTo(zong, temp.Length);//将nums数组拷贝到zong数组中,其实位置为zong[temp.Length]
         Array.ConstrainedCopy(zong, 0, nums,0 ,nums.Length ); //将总的数组拷贝到nums数组中,其中zong的起始位置为zong[0],nums的起始位置为nums[0],拷贝的长度为nums.Length
          } 
       } 
    }

    非常可惜的是,虽然题目要求是用3中做法做出来,但是我只能想出来一种。

    本题注意点:

    1 可能出现k>nums.Length的情况,此时k%nums.Length即可排除一个轮换周期

    2 刚开始用了两个嵌套for循环,可是提示time error,可见这种模式太耗时间,应该少用

    在Disacuss中见到了一个非常简洁的算法:

    public class Solution {
        public void Rotate(int[] nums, int k) {
           k=k%nums.Length;
           int[] numsCopy=new int[nums.Length];
           if(k!=0)
           {
               for(int i=0;i<nums.Length;i++)
              {
               numsCopy[i]=nums[i];
              }
              
              for(int i=0;i<nums.Length;i++)
              {
                  nums[(i+k)%nums.Length]=numsCopy[i];
              }
           }
        }
    }

    其中nums[(i+k)%nums.Length]=numsCopy[i];这句非常巧妙的利用取余运算!

    看了上面的代码,我意识到数组的传值需要用一个for循环,不应该直接传地址。因此将我原来的代码稍作修改:将

     Array.ConstrainedCopy(zong, 0, nums,0 ,nums.Length );修改为一个for循环:
     for (int i=0;i<nums.Length;i++)
          {
              nums[i]=zong[i];
          }

    这样也可以Accepted!

    这里还有一个我至今没有看懂的方法,先放在这里,期待以后可以看懂:

    public class Solution {
        public void Rotate(int[] nums, int k) {     
          int sz,n,temp;
          sz=n=nums.Length;
          k%=n;
          if(n<2 || k<1) return;
          for(int i=k;n>0;++i)
          {
                int j=i, prev=nums[(i-k)%k];
                while(n-->0) 
                {
                   //Interlocked.Exchange(prev,nums[j]);
                   temp=nums[j];
                   nums[j]=prev;
                   prev=temp;
                   j=(j+k)%sz;
                   if(j==i) break;
                }
          }
       } 
    }

     很高兴 今天把它看懂了,这里就贴上源代码以及我的理解:

    public class Solution {
        public void Rotate(int[] nums, int k) {     
          int sz,n,temp;
          sz=n=nums.Length;
          k%=n;
          if(n<2 || k<1) return;
          for(int i=k;n>0;++i)
          {
                int j=i, prev=nums[(i-k)%k];
                while(n-->0) 
                {
                   //Interlocked.Exchange(prev,nums[j]);
                   temp=nums[j];
                   nums[j]=prev;
                   prev=temp;
                   j=(j+k)%sz;   //如果把这个数组看成一个循环列表,这样每进行完一次j=(j+k)%sz,指针就会前移k格,将该位置的数更新
                if(j==i) break; //如果某一次前进k格又到了初始位置,此时在循环的话和上次循环的效果一样,所以应该跳出循环,同时利用下一个位置的数字作为初始的值,进行第二次循环,一直如此往复,知道所有的值都更新完成。由于条件限制,一共只会自行n次,每次更新一个数字,正好全部更新完毕
                 } 
    }
    }
    }
  • 相关阅读:
    列式存储hbase系统架构学习
    使用Phoenix通过sql语句更新操作hbase数据
    分布式实时日志系统(四) 环境搭建之centos 6.4下hbase 1.0.1 分布式集群搭建
    布式实时日志系统(三) 环境搭建之centos 6.4下hadoop 2.5.2完全分布式集群搭建最全资料
    GDI+绘制五星红旗
    C#模拟登录后请求查询
    ubuntu下安装mysql
    配置nginx实现windows/iis应用负载均衡
    23种设计模式之原型模式(Prototype)
    23种设计模式之访问者模式(Visitor)
  • 原文地址:https://www.cnblogs.com/xiaohua92/p/5260614.html
Copyright © 2011-2022 走看看