板子:区间逆置与循环左移
把数组看成
两段,想得到 :先两段各自逆置得到 ,再整体逆置, 。
代码
void reverse(int A[], int l, int r) { // 逆置 A[l..r],闭区间
while (l < r) { // l == r 时只剩中间一个,不用换
int t = A[l]; A[l++] = A[r]; A[r--] = t; // 交换两端,再往中间收
}
}
void rotateLeft(int A[], int n, int p) { // 循环左移 p 位
p %= n; // p >= n 时先取模:左移 n 位等于没动
reverse(A, 0, p - 1); // a = A[0..p-1] 逆置
reverse(A, p, n - 1); // b = A[p..n-1] 逆置
reverse(A, 0, n - 1); // 整体逆置,得到 ba
}复杂度:时间
例:1 2 3 4 5 6 7,3 2 1 | 7 6 5 4 → 4 5 6 7 1 2 3。
考场答案样例(2010)
题意:一维数组
(1)设计思想:把数组看成
(2)算法实现:就是上面的代码。
(3)复杂度:三次逆置分别交换
变形
- 循环右移
位 = 循环左移 位。 - 数组
A[m+n]前个和后 个整体换位置(王道 2.2 综合题):就是循环左移 位。 - 逆置整个顺序表:
reverse(A, 0, n - 1)。 - 保底解:用辅助数组先存下前
个,其余元素前移,再把存下的放回末尾。时间 ,空间 ,也是正确解。
易错点
reverse的区间是闭区间,第二段从 p开始,不是从p + 1开始。- 三次逆置可以换成先整体再两段,但分界点要改成
: reverse(0, n-1); reverse(0, n-p-1); reverse(n-p, n-1)。两种写法混着用就会错。
链接
- 📕 返回:数据结构代码板子
- ⬅️ 上一篇:算法题答题三段式
- ➡️ 下一篇:删除所有值为 x 的元素
- 🔗 算法题答题三段式
- 🔗 速查:顺序表与链表