数组的旋转的解法
来源:互联网 发布:园林效果图设计软件 编辑:程序博客网 时间:2024/05/21 06:46
数组长度为n,向右旋转k(0 <=k<=n)
方法一
(1) 如果k=0或者k=n,直接返回
(2) 否则,将[0,n-1]数组元素反转,然后[0, k-1]返回,[k,n-1]反转
代码如下class Solution{public:void rotate(vector<int>&nums, int k){int len = nums.size();if (k == 0 || k == len) return;int start = 0, end = len - 1;while (start < end){swap(nums[start], nums[end]);start++, end--;}start = 0, end = k - 1;while (start < end){swap(nums[start], nums[end]);start++, end--;}start = k, end = len - 1;while (start < end){swap(nums[start], nums[end]);start++, end--;}}};
方法二
(1) 如果k=0或者k=n,直接返回
(2) 将两段数据数据依次交换,隔开的位置为middle=n-k,两段数据的起始位置依次为first1=0,first2=middle,遍历first2直到first2=len,过程中如果first1=middle,将middle=first2
(3) 将first2=middle,再次遍历直到first2=len,过程中如果first1=middle,将middle=first2,注意在first1不等于middle但是first2=len时,将first2=middle
代码如下class Solution{public: void rotate(vector<int>& nums, int k) { int len = nums.size(); if (k == 0 || k == len) return; int middle = len - k; int first1 = 0, first2 = middle; do { swap(nums[first1], nums[first2]); first1++, first2++; if (first1 == middle) { middle = first2; } } while (first2 != len); first2 = middle; while (first2 != len) { swap(nums[first1], nums[first2]); first1++, first2++; if (first1 == middle) { middle = first2; } else if (first2 == len) { first2 = middle; } } }};
方法三
(1) 如果两段数据长度相等,直接相互替换返回
(2) 否则,计算n与(n-k)的最大公约数d,循环d次,如果n-k<k,在循环过程中,当下标大于k时,往回退a[cur]=a[cur-k],cur-=k,其它就正常操作a[cur]=a[cur+k],cur+=k
(3) 如果n-k>k,在循环过程中,当下标加上n-k没有越界时,a[cur]=a[cur+n-k],cur+=n-k,其它就正常操作a[cur]=a[cur-k],cur-=k
代码如下class Solution{public:void rotate(vector<int>&nums, int k){int n = nums.size();int a = n - k, b = k;if (a == b){int first1 = 0, first2 = k;for (int i = 0; i < k; i++) {swap(nums[first1], nums[first2]);first1++, first2++;}return;}int d = gcd(a, n);int tmp;int p = 0;for (int i = 0; i < d; i++){tmp = nums[i];p = i;if (a < b){for (int j = 0; j < b / d; j++){if (p > i + b){nums[p] = nums[p - b];p -= b;}nums[p] = nums[p + a];p += a;}}else{for (int j = 0; j < a / d - 1; j++){if (p + a < n){nums[p] = nums[p + a];p += a;}nums[p] = nums[p - b];p -= b;}}nums[p] = tmp;}}private:int gcd(int n, int m){if (m == 0) return n;else{return gcd(m, n % m);}}};
测试代码为
const int N = 7;int main(){vector<int> source;for (int i = 0; i < N; i++){source.push_back(i + 1);}Solution solver;for (int i = 0; i < N + 1; i++){vector<int> test = source;solver.rotate(test, i);copy(test.begin(), test.end(), ostream_iterator<int>(cout, " "));cout << endl;}return 0;}
0 0
- 数组的旋转的解法
- 旋转数组的最小值 の 暴力解法
- 旋转数组的最小值 の 三指针解法
- 字符串的左旋转最佳解法
- 数组求和的一个解法
- josephus 问题的数组解法
- 约瑟夫问题的数组解法
- 数组的旋转
- 旋转数组的最小值
- 旋转数组的查找
- 旋转数组的最小值
- 旋转数组的最小值
- 数组的旋转
- 旋转数组的最小值
- 旋转数组的最小值
- 旋转数组的最小值
- 旋转数组的最小值
- 旋转数组的最小值
- 生涯四度——提升你的生活效能
- CSAPP lab binary bomb 二进制炸弹
- httpModules 与 httpHandlers
- Oracle创建表空间,用户以及授权,查看权限
- 设计模式--迭代器模式
- 数组的旋转的解法
- Cocos2D游戏之旅(三):卡牌翻转效果的实现(上)
- 如何分析解决Android ANR
- dedecms判断使用方面 [field:global runphp='yes' name=autoindex]
- POJ - 3281 Dining (ISAP EK Dinic)
- 自签名证书和私有CA签名的证书的区别 创建自签名证书 创建私有CA 证书类型 证书扩展名
- 面向对象1
- android imeAction 的使用(改变软件键盘回车键的功能与显示文字)
- Oracle远程连接数据库解决方案